Portability | see LANGUAGE pragma |
---|---|
Stability | experimental |
Maintainer | [email protected] |
Control.Compose
Contents
Description
Various type constructor compositions and instances for them. Some come from "Applicative Programming with Effects" http://www.soi.city.ac.uk/~ross/papers/Applicative.html
- type Unop a = a -> a
- type Binop a = a -> a -> a
- class Cofunctor acc where
- cofmap :: (a -> b) -> acc b -> acc a
- bicomap :: Cofunctor f => (a :<->: b) -> f a :<->: f b
- newtype (g :. f) a = O {
- unO :: g (f a)
- type O = :.
- biO :: g (f a) :<->: (g :. f) a
- convO :: Functor g => (b :<->: g c) -> (c :<->: f a) -> b :<->: (g :. f) a
- coconvO :: Cofunctor g => (b :<->: g c) -> (c :<->: f a) -> b :<->: (g :. f) a
- inO :: (g (f a) -> g' (f' a')) -> (g :. f) a -> (g' :. f') a'
- inO2 :: (g (f a) -> g' (f' a') -> g'' (f'' a'')) -> (g :. f) a -> (g' :. f') a' -> (g'' :. f'') a''
- inO3 :: (g (f a) -> g' (f' a') -> g'' (f'' a'') -> g''' (f''' a''')) -> (g :. f) a -> (g' :. f') a' -> (g'' :. f'') a'' -> (g''' :. f''') a'''
- oPure :: Applicative g => f a -> (g :. f) a
- oFmap :: Functor g' => (f a -> f' a') -> (g' :. f) a -> (g' :. f') a'
- oLiftA2 :: Applicative g'' => (f a -> f' a' -> f'' a'') -> (g'' :. f) a -> (g'' :. f') a' -> (g'' :. f'') a''
- oLiftA3 :: Applicative g''' => (f a -> f' a' -> f'' a'' -> f''' a''') -> (g''' :. f) a -> (g''' :. f') a' -> (g''' :. f'') a'' -> (g''' :. f''') a'''
- fmapFF :: (Functor g, Functor f) => (a -> b) -> (g :. f) a -> (g :. f) b
- fmapCC :: (Cofunctor g, Cofunctor f) => (a -> b) -> (g :. f) a -> (g :. f) b
- cofmapFC :: (Functor g, Cofunctor f) => (b -> a) -> (g :. f) a -> (g :. f) b
- cofmapCF :: (Cofunctor g, Functor f) => (b -> a) -> (g :. f) a -> (g :. f) b
- newtype OO f (~>) a b = OO {
- unOO :: f (a ~> b)
- newtype FunA h a b = FunA {
- unFunA :: h a -> h b
- inFunA :: ((h a -> h b) -> h' a' -> h' b') -> FunA h a b -> FunA h' a' b'
- inFunA2 :: ((h a -> h b) -> (h' a' -> h' b') -> h'' a'' -> h'' b'') -> FunA h a b -> FunA h' a' b' -> FunA h'' a'' b''
- class FunAble h where
- class Monoid_f m where
- newtype Flip (~>) b a = Flip {
- unFlip :: a ~> b
- biFlip :: (a ~> b) :<->: Flip ~> b a
- inFlip :: ((a ~> b) -> a' ~~> b') -> Flip ~> b a -> Flip ~~> b' a'
- inFlip2 :: ((a ~> b) -> (a' ~~> b') -> a'' ~~~> b'') -> Flip ~> b a -> Flip ~~> b' a' -> Flip ~~~> b'' a''
- inFlip3 :: ((a ~> b) -> (a' ~~> b') -> (a'' ~~~> b'') -> a''' ~~~~> b''') -> Flip ~> b a -> Flip ~~> b' a' -> Flip ~~~> b'' a'' -> Flip ~~~~> b''' a'''
- type OI = Flip (->) (IO ())
- class ToOI sink where
- newtype f :$ a = App {
- unApp :: f a
- type App = :$
- biApp :: f a :<->: App f a
- inApp :: (f a -> f' a') -> App f a -> App f' a'
- inApp2 :: (f a -> f' a' -> f'' a'') -> App f a -> App f' a' -> App f'' a''
- newtype Id a = Id {
- unId :: a
- biId :: a :<->: Id a
- inId :: (a -> b) -> Id a -> Id b
- inId2 :: (a -> b -> c) -> Id a -> Id b -> Id c
- newtype (f :*: g) a = Prod {
- unProd :: (f a, g a)
- biProd :: (f a, g a) :<->: (f :*: g) a
- convProd :: (b :<->: f a) -> (c :<->: g a) -> (b, c) :<->: (f :*: g) a
- (***#) :: (a -> b -> c) -> (a' -> b' -> c') -> (a, a') -> (b, b') -> (c, c')
- ($*) :: (a -> b, a' -> b') -> (a, a') -> (b, b')
- inProd :: ((f a, g a) -> (f' a', g' a')) -> (f :*: g) a -> (f' :*: g') a'
- inProd2 :: ((f a, g a) -> (f' a', g' a') -> (f'' a'', g'' a'')) -> (f :*: g) a -> (f' :*: g') a' -> (f'' :*: g'') a''
- inProd3 :: ((f a, g a) -> (f' a', g' a') -> (f'' a'', g'' a'') -> (f''' a''', g''' a''')) -> (f :*: g) a -> (f' :*: g') a' -> (f'' :*: g'') a'' -> (f''' :*: g''') a'''
- newtype (f ::*:: g) a b = Prodd {
- unProdd :: (f a b, g a b)
- inProdd :: ((f a b, g a b) -> (f' a' b', g' a' b')) -> (f ::*:: g) a b -> (f' ::*:: g') a' b'
- inProdd2 :: ((f a b, g a b) -> (f' a' b', g' a' b') -> (f'' a'' b'', g'' a'' b'')) -> (f ::*:: g) a b -> (f' ::*:: g') a' b' -> (f'' ::*:: g'') a'' b''
- newtype Arrw (~>) f g a = Arrw {
- unArrw :: f a ~> g a
- type :->: = Arrw (->)
- biFun :: (f a -> g a) :<->: (f :->: g) a
- convFun :: (b :<->: f a) -> (c :<->: g a) -> (b -> c) :<->: (f :->: g) a
- inArrw :: ((f a ~> g a) -> f' a' ~> g' a') -> Arrw ~> f g a -> Arrw ~> f' g' a'
- inArrw2 :: ((f a ~> g a) -> (f' a' ~> g' a') -> f'' a'' ~> g'' a'') -> Arrw ~> f g a -> Arrw ~> f' g' a' -> Arrw ~> f'' g'' a''
- inArrw3 :: ((f a ~> g a) -> (f' a' ~> g' a') -> (f'' a'' ~> g'' a'') -> f''' a''' ~> g''' a''') -> Arrw ~> f g a -> Arrw ~> f' g' a' -> Arrw ~> f'' g'' a'' -> Arrw ~> f''' g''' a'''
- biConst :: a :<->: Const a b
- inConst :: (a -> b) -> Const a u -> Const b v
- inConst2 :: (a -> b -> c) -> Const a u -> Const b v -> Const c w
- inConst3 :: (a -> b -> c -> d) -> Const a u -> Const b v -> Const c w -> Const d x
- biEndo :: (a -> a) :<->: Endo a
- inEndo :: (Unop a -> Unop a') -> Endo a -> Endo a'
Documentation
Contravariant functors
class Cofunctor acc whereSource
Contravariant functors. often useful for acceptors (consumers, sinks) of values.
Unary/unary composition
Composition of unary type constructors
There are (at least) two useful Monoid
instances, so you'll have to
pick one and type-specialize it (filling in all or parts of g
and/or f
).
-- standard Monoid instance for Applicative applied to Monoid instance (Applicative (g :. f), Monoid a) => Monoid ((g :. f) a) where { mempty = pure mempty; mappend = liftA2 mappend } -- Especially handy when g is a Monoid_f. instance Monoid (g (f a)) => Monoid ((g :. f) a) where { mempty = O mempty; mappend = inO2 mappend }
Corresponding to the first and second definitions above,
instance (Applicative g, Monoid_f f) => Monoid_f (g :. f) where { mempty_f = O (pure mempty_f); mappend_f = inO2 (liftA2 mappend_f) } instance Monoid_f g => Monoid_f (g :. f) where { mempty_f = O mempty_f; mappend_f = inO2 mappend_f }
Similarly, there are two useful Functor
instances and two useful
Cofunctor
instances.
instance ( Functor g, Functor f) => Functor (g :. f) where fmap = fmapFF instance (Cofunctor g, Cofunctor f) => Functor (g :. f) where fmap = fmapCC instance (Functor g, Cofunctor f) => Cofunctor (g :. f) where cofmap = cofmapFC instance (Cofunctor g, Functor f) => Cofunctor (g :. f) where cofmap = cofmapCF
However, it's such a bother to define the Functor instances per composition type, I've left the fmapFF case in. If you want the fmapCC one, you're out of luck for now. I'd love to hear a good solution. Maybe someday Haskell will do Prolog-style search for instances, subgoaling the constraints, rather than just matching instance heads.
Instances
Applicative f => Lambda f (:. (Flip (->) o) f) | |
Applicative f => Lambda f (:. f (Flip (->) o)) | |
(Functor g, Functor f) => Functor (:. g f) | |
(Applicative g, Applicative f) => Applicative (:. g f) | |
(Foldable g, Foldable f, Functor g) => Foldable (:. g f) | |
(Traversable g, Traversable f) => Traversable (:. g f) | |
Title_f g => Title_f (:. g f) | |
(Functor h, Copair f) => Copair (:. h f) | |
(Functor h, Cozip f) => Cozip (:. h f) |
convO :: Functor g => (b :<->: g c) -> (c :<->: f a) -> b :<->: (g :. f) aSource
Compose a bijection, Functor style
coconvO :: Cofunctor g => (b :<->: g c) -> (c :<->: f a) -> b :<->: (g :. f) aSource
Compose a bijection, Cofunctor style
inO :: (g (f a) -> g' (f' a')) -> (g :. f) a -> (g' :. f') a'Source
Apply a unary function within the O
constructor.
inO2 :: (g (f a) -> g' (f' a') -> g'' (f'' a'')) -> (g :. f) a -> (g' :. f') a' -> (g'' :. f'') a''Source
Apply a binary function within the O
constructor.
inO3 :: (g (f a) -> g' (f' a') -> g'' (f'' a'') -> g''' (f''' a''')) -> (g :. f) a -> (g' :. f') a' -> (g'' :. f'') a'' -> (g''' :. f''') a'''Source
Apply a ternary function within the O
constructor.
oLiftA2 :: Applicative g'' => (f a -> f' a' -> f'' a'') -> (g'' :. f) a -> (g'' :. f') a' -> (g'' :. f'') a''Source
oLiftA3 :: Applicative g''' => (f a -> f' a' -> f'' a'' -> f''' a''') -> (g''' :. f) a -> (g''' :. f') a' -> (g''' :. f'') a'' -> (g''' :. f''') a'''Source
fmapFF :: (Functor g, Functor f) => (a -> b) -> (g :. f) a -> (g :. f) bSource
Used for the Functor :. Functor
instance of Functor
fmapCC :: (Cofunctor g, Cofunctor f) => (a -> b) -> (g :. f) a -> (g :. f) bSource
Used for the Cofunctor :. Cofunctor
instance of Functor
cofmapFC :: (Functor g, Cofunctor f) => (b -> a) -> (g :. f) a -> (g :. f) bSource
Used for the Functor :. Cofunctor
instance of Functor
cofmapCF :: (Cofunctor g, Functor f) => (b -> a) -> (g :. f) a -> (g :. f) bSource
Used for the Cofunctor :. Functor
instance of Functor
Type composition
Unary/binary
Composition of type constructors: unary with binary. Called StaticArrow in [1].
Instances
(Applicative f, Arrow ~>) => Arrow (OO f ~>) | |
(Applicative f, Category ~>) => Category (OO f ~>) |
(->)/unary
Common pattern for Arrow
s.
inFunA :: ((h a -> h b) -> h' a' -> h' b') -> FunA h a b -> FunA h' a' b'Source
Apply unary function in side a FunA
representation.
inFunA2 :: ((h a -> h b) -> (h' a' -> h' b') -> h'' a'' -> h'' b'') -> FunA h a b -> FunA h' a' b' -> FunA h'' a'' b''Source
Apply binary function in side a FunA
representation.
Monoid constructors
Simulates universal constraint forall a. Monoid (f a)
.
See Simulating Quantified Class Constraints (http://flint.cs.yale.edu/trifonov/papers/sqcc.pdf) Instantiate this schema wherever necessary:
instance Monoid_f f where { mempty_f = mempty ; mappend_f = mappend }
Flip a binary constructor's type arguments
Flip type arguments
Instances
Applicative f => Lambda f (:. (Flip (->) o) f) | |
Applicative f => Lambda f (:. f (Flip (->) o)) | |
Lambda Id (Flip (->) o) | |
Monoid o => Monoid_f (Flip (->) o) | |
Arrow ~> => Cofunctor (Flip ~> b) | |
Title o => Title_f (Flip (->) o) | |
Arrow ~> => Copair (Flip ~> o) | |
(Arrow ~>, Monoid_f (Flip ~> o)) => Pair (Flip ~> o) | |
Arrow ~> => Cozip (Flip ~> o) | |
(Arrow ~>, Monoid_f (Flip ~> o)) => Zip (Flip ~> o) | |
(Applicative (~> a), Monoid o) => Monoid (Flip ~> o a) |
inFlip2 :: ((a ~> b) -> (a' ~~> b') -> a'' ~~~> b'') -> Flip ~> b a -> Flip ~~> b' a' -> Flip ~~~> b'' a''Source
inFlip3 :: ((a ~> b) -> (a' ~~> b') -> (a'' ~~~> b'') -> a''' ~~~~> b''') -> Flip ~> b a -> Flip ~~> b' a' -> Flip ~~~> b'' a'' -> Flip ~~~~> b''' a'''Source
Type application
Type application
We can also drop the App
constructor, but then we overlap with many
other instances, like [a]
. Here's a template for App
-free
instances.
instance (Applicative f, Monoid a) => Monoid (f a) where mempty = pure mempty mappend = liftA2 mappend
Identity
Identity type constructor. Until there's a better place to find it. I'd use Control.Monad.Identity, but I don't want to introduce a dependency on mtl just for Id.
Constructor pairing
Unary
Pairing of unary type constructors
Instances
(Functor f, Functor g) => Functor (:*: f g) | |
(Applicative f, Applicative g) => Applicative (:*: f g) | |
(Monoid_f f, Monoid_f g) => Monoid_f (:*: f g) | |
(Copair f, Copair g) => Copair (:*: f g) | |
(Pair f, Pair g) => Pair (:*: f g) | |
(Cozip f, Cozip g) => Cozip (:*: f g) | |
(Zip f, Zip g) => Zip (:*: f g) | |
(Lambda src snk, Lambda dom' ran') => Lambda (:*: src dom') (:*: snk ran') | |
Eq (f a, g a) => Eq (:*: f g a) | |
Ord (f a, g a) => Ord (:*: f g a) | |
Show (f a, g a) => Show (:*: f g a) |
(***#) :: (a -> b -> c) -> (a' -> b' -> c') -> (a, a') -> (b, b') -> (c, c')Source
Combine two binary functions into a binary function on pairs
($*) :: (a -> b, a' -> b') -> (a, a') -> (b, b')Source
A handy combining form. See '(***#)' for an sample use.
inProd :: ((f a, g a) -> (f' a', g' a')) -> (f :*: g) a -> (f' :*: g') a'Source
Apply unary function inside of f :*: g
representation.
inProd2 :: ((f a, g a) -> (f' a', g' a') -> (f'' a'', g'' a'')) -> (f :*: g) a -> (f' :*: g') a' -> (f'' :*: g'') a''Source
Apply binary function inside of f :*: g
representation.
inProd3 :: ((f a, g a) -> (f' a', g' a') -> (f'' a'', g'' a'') -> (f''' a''', g''' a''')) -> (f :*: g) a -> (f' :*: g') a' -> (f'' :*: g'') a'' -> (f''' :*: g''') a'''Source
Apply ternary function inside of f :*: g
representation.
Binary
inProdd :: ((f a b, g a b) -> (f' a' b', g' a' b')) -> (f ::*:: g) a b -> (f' ::*:: g') a' b'Source
Apply binary function inside of f :*: g
representation.
inProdd2 :: ((f a b, g a b) -> (f' a' b', g' a' b') -> (f'' a'' b'', g'' a'' b'')) -> (f ::*:: g) a b -> (f' ::*:: g') a' b' -> (f'' ::*:: g'') a'' b''Source
Apply binary function inside of f :*: g
representation.
Arrow between two constructor applications
newtype Arrw (~>) f g a Source
Arrow-like type between type constructors (doesn't enforce Arrow
(~>)
here).
Instances
(Arrow ~>, Cofunctor f, Functor g) => Functor (Arrw ~> f g) | |
(Arrow ~>, Functor f, Cofunctor g) => Cofunctor (Arrw ~> f g) | |
(Arrow ~>, Unpair f, Pair g) => Pair (Arrw ~> f g) | |
(Arrow ~>, Unzip f, Zip g) => Zip (Arrw ~> f g) | |
(Arrow ~>, Unlambda f f', Lambda g g') => Lambda (Arrw ~> f g) (Arrw ~> f' g') | |
Monoid (~> (f a) (g a)) => Monoid (Arrw ~> f g a) |
inArrw :: ((f a ~> g a) -> f' a' ~> g' a') -> Arrw ~> f g a -> Arrw ~> f' g' a'Source
Apply unary function inside of Arrw
representation.
inArrw2 :: ((f a ~> g a) -> (f' a' ~> g' a') -> f'' a'' ~> g'' a'') -> Arrw ~> f g a -> Arrw ~> f' g' a' -> Arrw ~> f'' g'' a''Source
Apply binary function inside of Arrw (~>) f g
representation.
inArrw3 :: ((f a ~> g a) -> (f' a' ~> g' a') -> (f'' a'' ~> g'' a'') -> f''' a''' ~> g''' a''') -> Arrw ~> f g a -> Arrw ~> f' g' a' -> Arrw ~> f'' g'' a'' -> Arrw ~> f''' g''' a'''Source
Apply ternary function inside of Arrw (~>) f g
representation.