Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
Synopsis
- type (~>) f g = forall a. f a -> g a
- class forall f. Functor f => Functor (h f) => Functor1 (h :: (* -> *) -> * -> *) where
- class Functor1 h => Strong1 h where
- data Either2 (h :: (* -> *) -> * -> *) (j :: (* -> *) -> * -> *) (f :: * -> *) (a :: *)
- data Var (f :: * -> *) (a :: *) = Var a
- newtype Assigned (r :: *) (v :: *) (a :: *) = Assigned ((a -> v) -> r)
- class forall f p. forall q. Functor (f q) => Functor (h f p) => PFunctor1 (h :: (k -> * -> *) -> k -> * -> *)
- newtype Mu (h :: (* -> *) -> * -> *) (a :: *) = Roll {}
- cata1 :: (Functor1 h, Functor f) => (h f ~> f) -> Mu h ~> f
- data MMu (h :: (k -> * -> *) -> k -> * -> *) (p :: k) (a :: *)
- pcata1 :: (PFunctor1 h, forall q. Functor (f q)) => (forall q. h f q ~> f q) -> MMu h p ~> f p
- class GFunctor1 (h :: * -> *) (j :: * -> *) (f :: * -> *) (g :: * -> *)
- class GStrong1 (h :: * -> *) (j :: * -> *) (f :: * -> *) (g :: * -> *) (i :: * -> *)
Functors of endofunctors
Simple functors
class forall f. Functor f => Functor (h f) => Functor1 (h :: (* -> *) -> * -> *) where Source #
class Functor1 h => Strong1 h where Source #
The intuition behind Strong1 h
is that h
acts on monads. Indeed if
f=g=m
is a monad, then x -> strength1 x join :: h m (m a) -> h m a
. This
is a limited explanation, but I don't know much more yet.
As additional background, for the curious programmer: from a mathematical
point of view, strenght1
is a functorial strength. For regular functors, a
strength is a function (f a, b) -> f (a, b)
. But for regular functor, there
is always such a strength: (fa, b) -> (, b) $ fa
(this strength is
implicitly but critically used in the definition of the do-notation).
However functors of endofunctors don't necessarily have a strength (in fact
Var
below doesn't have one). So we need an additional type class to record
that functors are strong.
Like in the infamous phrase "a monad is a monoid in the category of
endofunctors", the natural product of endofunctors is composition. It is not
hard to verify that, up to map1
, the type of strength1
is equivalent to
h f
. We choose this formulation because it
avoids annotations to convert between Compose
g ~> h (f Compose
g)Compose f g a
and f (g a)
.
In any case, this is a natural notion from a mathematics point of view. And
not as ad hoc as it may appear at first glance. However, because we
wouldn't have interesting instance without it, we restrict g
to be an
applicative functor. There does not seem to be a need for f
to be
applicative as well, therefore we depart from usual mathematical practice and
only restrict g
.
data Either2 (h :: (* -> *) -> * -> *) (j :: (* -> *) -> * -> *) (f :: * -> *) (a :: *) Source #
Instances
data Var (f :: * -> *) (a :: *) Source #
Var a |
Instances
Functor1 Var Source # | |
Strong1 h => Monad (Mu (Either2 Var h)) Source # | |
Functor (Var f) Source # | |
Strong1 h => Applicative (Mu (Either2 Var h)) Source # | |
pure :: a -> Mu (Either2 Var h) a # (<*>) :: Mu (Either2 Var h) (a -> b) -> Mu (Either2 Var h) a -> Mu (Either2 Var h) b # liftA2 :: (a -> b -> c) -> Mu (Either2 Var h) a -> Mu (Either2 Var h) b -> Mu (Either2 Var h) c # (*>) :: Mu (Either2 Var h) a -> Mu (Either2 Var h) b -> Mu (Either2 Var h) b # (<*) :: Mu (Either2 Var h) a -> Mu (Either2 Var h) b -> Mu (Either2 Var h) a # | |
Generic1 (Var f :: * -> *) Source # | |
Eq a => Eq (Var f a) Source # | |
type Rep1 (Var f :: * -> *) Source # | |
newtype Assigned (r :: *) (v :: *) (a :: *) Source #
represent the computation of a result Assigned
r v ar
parametrised
by an assignment of values of type v
to each element of a
. It is a
functor (in a
).
Its usefulness derives from the fact that given a Functor1
F
, an algebra
of F
on Assigned R V
yields, via catamorphism (see cata1
) an algebra of
the monad Mu F
. That is a compositional interpreter for Mu F
in the
type R
. This is used a lot.
You may have noticed that Assigned r r
is a monad (the continuation monad
, in fact). As a matter of fact Cont
rAssigned
is an indexed monad (up,
possibly, to the order of its arguments) which is related to delimited
continuation. Neither of this fact are useful for our purposes
Assigned ((a -> v) -> r) |
Parametric functors
class forall f p. forall q. Functor (f q) => Functor (h f p) => PFunctor1 (h :: (k -> * -> *) -> k -> * -> *) Source #
pfmap1
Non-uniform fixed point
Simple fixed point
newtype Mu (h :: (* -> *) -> * -> *) (a :: *) Source #
Instances
Strong1 h => Monad (Mu (Either2 Var h)) Source # | |
Functor1 h => Functor (Mu h) Source # | |
Strong1 h => Applicative (Mu (Either2 Var h)) Source # | |
pure :: a -> Mu (Either2 Var h) a # (<*>) :: Mu (Either2 Var h) (a -> b) -> Mu (Either2 Var h) a -> Mu (Either2 Var h) b # liftA2 :: (a -> b -> c) -> Mu (Either2 Var h) a -> Mu (Either2 Var h) b -> Mu (Either2 Var h) c # (*>) :: Mu (Either2 Var h) a -> Mu (Either2 Var h) b -> Mu (Either2 Var h) b # (<*) :: Mu (Either2 Var h) a -> Mu (Either2 Var h) b -> Mu (Either2 Var h) a # | |
(Eq a, forall b (f :: * -> *). (Eq b, forall c. Eq c => Eq (f c)) => Eq (h f b)) => Eq (Mu h a) Source # | |
Mutually recursive fixed point
pcata1 :: (PFunctor1 h, forall q. Functor (f q)) => (forall q. h f q ~> f q) -> MMu h p ~> f p Source #
Deriving instances
Deriving Functor1
class GFunctor1 (h :: * -> *) (j :: * -> *) (f :: * -> *) (g :: * -> *) Source #
A class for deriving Functor1
instances generic types. We would really
need a Generic2
framework (because our types have two arguments). Instead
we use an encoding trick, related to the way lenses are defined in the
lens library. This trick is due to
Csongor Kiss, and documented in
this blog post.
The intuition is that the first two argument h
and j
of the type class,
are stand-ins for h' f
and h' g
.
gfmap1
Instances
GFunctor1 Par1 Par1 f g Source # | |
GFunctor1 f g f g Source # | |
GFunctor1 (V1 :: * -> *) (V1 :: * -> *) f g Source # | |
GFunctor1 (U1 :: * -> *) (U1 :: * -> *) f g Source # | |
(Functor1 h, Functor f, Functor g) => GFunctor1 (Rec1 (h f)) (Rec1 (h g)) f g Source # | |
GFunctor1 (Rec1 i) (Rec1 i) f g Source # | |
GFunctor1 (Rec1 f) (Rec1 g) f g Source # | |
GFunctor1 (K1 i c :: * -> *) (K1 i c :: * -> *) g f Source # | |
(GFunctor1 h1 j1 f g, GFunctor1 h2 j2 f g) => GFunctor1 (h1 :+: h2) (j1 :+: j2) f g Source # | |
(GFunctor1 h1 j1 f g, GFunctor1 h2 j2 f g) => GFunctor1 (h1 :*: h2) (j1 :*: j2) f g Source # | |
GFunctor1 h j f g => GFunctor1 (M1 i c h) (M1 i c j) f g Source # | |
(GFunctor1 h1 j1 f g, GFunctor1 h2 j2 f g, Functor h1) => GFunctor1 (h1 :.: h2) (j1 :.: j2) f g Source # | |
Deriving Strong1
class GStrong1 (h :: * -> *) (j :: * -> *) (f :: * -> *) (g :: * -> *) (i :: * -> *) Source #
A class for deriving Strong1
instances generic types. See the
documentation of Functor1
for details on the encoding. You should read h
and j
below as being h' f
and h' i
, respectively.
gstrength1
Instances
GStrong1 f i f g i Source # | |
gstrength1 :: f (g a) -> (forall b. f (g b) -> i b) -> i a | |
GStrong1 (V1 :: * -> *) (V1 :: * -> *) f g i Source # | |
gstrength1 :: V1 (g a) -> (forall b. f (g b) -> i b) -> V1 a | |
GStrong1 (U1 :: * -> *) (U1 :: * -> *) f g i Source # | |
gstrength1 :: U1 (g a) -> (forall b. f (g b) -> i b) -> U1 a | |
GStrong1 (Rec1 f) (Rec1 i) f g i Source # | |
gstrength1 :: Rec1 f (g a) -> (forall b. f (g b) -> i b) -> Rec1 i a | |
(Strong1 h, Functor f, Applicative g, Functor i) => GStrong1 (Rec1 (h f)) (Rec1 (h i)) f g i Source # | |
gstrength1 :: Rec1 (h f) (g a) -> (forall b. f (g b) -> i b) -> Rec1 (h i) a | |
GStrong1 (K1 m c :: * -> *) (K1 m c :: * -> *) g f i Source # | |
gstrength1 :: K1 m c (f a) -> (forall b. g (f b) -> i b) -> K1 m c a | |
(GStrong1 h1 j1 f g i, GStrong1 h2 j2 f g i) => GStrong1 (h1 :+: h2) (j1 :+: j2) f g i Source # | |
gstrength1 :: (h1 :+: h2) (g a) -> (forall b. f (g b) -> i b) -> (j1 :+: j2) a | |
(GStrong1 h1 j1 f g i, GStrong1 h2 j2 f g i) => GStrong1 (h1 :*: h2) (j1 :*: j2) f g i Source # | |
gstrength1 :: (h1 :*: h2) (g a) -> (forall b. f (g b) -> i b) -> (j1 :*: j2) a | |
GStrong1 h j f g i => GStrong1 (M1 m c h) (M1 m c j) f g i Source # | |
gstrength1 :: M1 m c h (g a) -> (forall b. f (g b) -> i b) -> M1 m c j a | |
(GStrong1 h1 j1 f g i, Traversable t, Functor h1, Traversable t, Applicative g) => GStrong1 (h1 :.: t) (j1 :.: t) f g i Source # | |
gstrength1 :: (h1 :.: t) (g a) -> (forall b. f (g b) -> i b) -> (j1 :.: t) a |