| Portability | RankNTypes |
|---|---|
| Stability | provisional |
| Maintainer | Edward Kmett <ekmett@gmail.com> |
| Safe Haskell | Safe-Infered |
Control.Lens.Representable
Contents
Description
Corepresentable endofunctors represented by their polymorphic lenses
The polymorphic lenses of the form (forall x. Lens (f x) x) each
represent a distinct path into a functor f. If the functor is entirely
characterized by assigning values to these paths, then the functor is
representable.
Consider the following example.
import Control.Lens import Control.Lens.Representable import Control.Lens.TH import Data.Distributive
data Pair a = Pair { _x :: a, _y :: a }
makeLenses ''Pair
instance Representable Pair where rep f = Pair (f x) (f y)
From there, you can get definitions for a number of instances for free.
instance Applicative Pair where pure = pureRep (<*>) = apRep
instance Monad Pair where return = pureRep (>>=) = bindRep
instance Distributive Pair where distribute = distributeRep
- class Functor f => Representable f where
- type Rep f = forall a. Simple Lens (f a) a
- fmapRep :: Representable f => (a -> b) -> f a -> f b
- pureRep :: Representable f => a -> f a
- apRep :: Representable f => f (a -> b) -> f a -> f b
- bindRep :: Representable f => f a -> (a -> f b) -> f b
- distributeRep :: (Representable f, Functor w) => w (f a) -> f (w a)
- newtype Key f = Key {}
- keys :: Representable f => f (Key f)
- mapWithRep :: Representable f => (Rep f -> a -> b) -> f a -> f b
- foldMapWithRep :: (Representable f, Foldable f, Monoid m) => (Rep f -> a -> m) -> f a -> m
- foldrWithRep :: (Representable f, Foldable f) => (Rep f -> a -> b -> b) -> b -> f a -> b
- traverseWithRep :: (Representable f, Traversable f, Applicative g) => (Rep f -> a -> g b) -> f a -> g (f b)
- traverseWithRep_ :: (Representable f, Foldable f, Applicative g) => (Rep f -> a -> g b) -> f a -> g ()
- forWithRep :: (Representable f, Traversable f, Applicative g) => f a -> (Rep f -> a -> g b) -> g (f b)
- mapMWithRep :: (Representable f, Traversable f, Monad m) => (Rep f -> a -> m b) -> f a -> m (f b)
- mapMWithRep_ :: (Representable f, Foldable f, Monad m) => (Rep f -> a -> m b) -> f a -> m ()
- forMWithRep :: (Representable f, Traversable f, Monad m) => f a -> (Rep f -> a -> m b) -> m (f b)
Representable Functors
class Functor f => Representable f whereSource
Representable Functors.
A Functor f is Representable if it is isomorphic to (x -> a)
for some x. All such functors can be represented by choosing x to be
the set of lenses that are polymorphic in the contents of the Functor,
that is to say x = Rep f is a valid choice of x for every
Representable Functor.
Note: Some sources refer to covariant representable functors as
corepresentable functors, and leave the "representable" name to
contravariant functors (those are isomorphic to (a -> x) for some x).
As the covariant case is vastly more common, and both are often referred to
as representable functors, we choose to call these functors Representable
here.
Instances
| Representable Identity | |
| Eq e => Representable ((->) e) | NB: The Eq requirement on this instance is a consequence of a lens
rather than |
Using Lenses as Representations
type Rep f = forall a. Simple Lens (f a) aSource
The representation of a Representable Functor as Lenses
Default definitions
fmapRep :: Representable f => (a -> b) -> f a -> f bSource
pureRep :: Representable f => a -> f aSource
apRep :: Representable f => f (a -> b) -> f a -> f bSource
bindRep :: Representable f => f a -> (a -> f b) -> f bSource
bindRep is a valid default default definition for '(>>=)' for a
representable functor.
bindRep m f = rep $ \i -> f(m^.i)^.i
Usage for a representable functor Foo:
instance Monad ... where return = pureRep (>>=) = bindRep
distributeRep :: (Representable f, Functor w) => w (f a) -> f (w a)Source
A default definition for distribute for a Representable Functor
distributeRep wf = rep $ \i -> fmap (^.i) wf
Typical Usage:
instance Distributive ... where distribute = distributeRep
Wrapped Representations
Sometimes you need to store a path lens into a container, but at least at this time, impredicative polymorphism in GHC is somewhat lacking.
This type provides a way to, say, store a list of polymorphic lenses.
keys :: Representable f => f (Key f)Source
A Representable Functor has a fixed shape. This fills each position
in it with a Key
Traversal with representation
mapWithRep :: Representable f => (Rep f -> a -> b) -> f a -> f bSource
Map over a Representable Functor with access to the lens for the
current position
mapWithKey f m = rep $ \i -> f i (m^.i)
foldMapWithRep :: (Representable f, Foldable f, Monoid m) => (Rep f -> a -> m) -> f a -> mSource
Fold over a Representable Functor with access to the current path
as a lens, yielding a Monoid
foldrWithRep :: (Representable f, Foldable f) => (Rep f -> a -> b -> b) -> b -> f a -> bSource
Fold over a Representable Functor with access to the current path
as a lens.
traverseWithRep :: (Representable f, Traversable f, Applicative g) => (Rep f -> a -> g b) -> f a -> g (f b)Source
Traverse a Representable Functor with access to the current path
traverseWithRep_ :: (Representable f, Foldable f, Applicative g) => (Rep f -> a -> g b) -> f a -> g ()Source
Traverse a Representable Functor with access to the current path
as a lens, discarding the result
forWithRep :: (Representable f, Traversable f, Applicative g) => f a -> (Rep f -> a -> g b) -> g (f b)Source
Traverse a Representable Functor with access to the current path
and a lens (and the arguments flipped)
mapMWithRep :: (Representable f, Traversable f, Monad m) => (Rep f -> a -> m b) -> f a -> m (f b)Source
mapM over a Representable Functor with access to the current path
as a lens
mapMWithRep_ :: (Representable f, Foldable f, Monad m) => (Rep f -> a -> m b) -> f a -> m ()Source
mapM over a Representable Functor with access to the current path
as a lens, discarding the result
forMWithRep :: (Representable f, Traversable f, Monad m) => f a -> (Rep f -> a -> m b) -> m (f b)Source
mapM over a Representable Functor with access to the current path
as a lens (with the arguments flipped)