简体   繁体   中英

How to use Data.Functor.Invariant?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM