Could someone please provide me an example of
invmap :: (a -> b) -> (b -> a) -> f a -> f b
and for what is Invariant good for?
Mostly, people don't use Invariant
. The reason you'd want to is if you're working with a type in which a variable appears in both covariant and contravariant positions.
newtype Endo a = Endo {appEndo :: a -> a}
newtype Foo a = Foo (Maybe a -> IO a)
data Bar a = Bar [a] (a -> Bool)
None of these are instances of Functor
or Contravariant
, but they can all be instances of Invariant
.
The reason people rarely bother is that if you need to do a lot of mapping over such a type, you're typically better off factoring it out into covariant and contravariant parts. Each invariant functor can be expressed in terms of a Profunctor
:
newtype FooP x y = FooP (Maybe x -> IO y)
data BarP x y = Bar [y] (x -> Bool)
Now
Endo a ~= (->) a a
Foo a ~= FooP a a
Bar a ~= BarP a a
-- So we'd likely write newtype Bar a = Bar (BarP a a)
It's generally easier to see what's going on if you unwrap the newtype
, dimap
over the underlying Profunctor
, and then wrap it up again rather than messing around with invmap
.
How can we transform an Invariant
functor into a Profunctor
? First, let's dispose of sums and products. If we can turn f
and g
into profunctors fp
and gp
, then we can surely turn f :+: g
and f :*: g
into equivalent profunctor sums and products.
What about compositions? It's slightly trickier, but not much. Suppose that we can turn f
and g
into profunctors fp
and gp
. Now define
-- Compose f g a ~= ComposeP fp gp a a
newtype ComposeP p q a b = ComposeP (p (q b a) (q a b))
instance (Profunctor p, Profunctor q) => Profunctor (ComposeP p q) where
dimap f g (ComposeP p) = ComposeP $ dimap (dimap g f) (dimap f g) p
Now suppose you have a function type; fa -> ga
. This looks like fp ba -> gp ab
.
I think that should cover most of the interesting cases.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.