ekmett / contravariant

Haskell 98 contravariant functors
http://hackage.haskell.org/package/contravariant
Other
73 stars 24 forks source link

What does `(a -> f a) -> f a` mean for contravariant applicatives? #36

Open jackfirth opened 7 years ago

jackfirth commented 7 years ago

I've run into this in a handful of cases where I've got a contravariant applicative and I want to "map it over" a list (more accurately an indexable container like a vector). This mapping ends up depending on the length of the list, as the logic goes like so:

  1. I've got an f a
  2. I've got an indexable container v a with size :: v a -> Int and a partial ref :: v a -> Int -> a function
  3. I can use contramap to take an index and convert f a to f (v a), where it only operates on the element at the index and ignores the others
  4. I can combine multiple instances of f a in a way that's just repeatedly applying divide with conquer as the empty case
  5. Given this, I can go from a list of indexes to a combined f (v a) that operates on the elements at those indexes
  6. Now I need to construct an f (v a) that gets the size of the input container, uses that size to construct a list of all indexes in v a, constructs a combined f (v a) operating on the elements at those indexes, then applies that combined f (v a) to the input container
  7. In order to do that, I need some sort of "dependent" constructor for an f that lets me turn any a -> f a function into an f a

I'm not sure if this something that Decidable can do or if the only reason using Decidable seems unintuitive to me is because of the partial nature of the ref function. For context, I mostly work with impure functional languages so a constant-time partial ref function is more idiomatic than it would be in Haskell.

Zemyla commented 4 years ago

Let's look at the types. For example, Op r a is a newtype wrapper around a -> r. So if we put Op r instead of f, we get

(a -> f a) -> f a === (a -> a -> r) -> a -> r

which is basically join @(->).

I'm not really sure how it should work for things like Equivalence or Comparison, though.