{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Fold.L
  ( L(..)
  , unfoldL
  ) where

import Control.Applicative
import Control.Comonad
import Control.Lens
import Control.Monad.Reader.Class
import Control.Monad.Fix
import Control.Monad.Zip
import Data.Distributive
import Data.Foldable
import Data.Fold.Class
import Data.Fold.Internal
import Data.Functor.Extend
import Data.Functor.Bind
import Data.Functor.Rep as Functor
import Data.Profunctor.Closed
import Data.Profunctor
import Data.Profunctor.Sieve
import Data.Profunctor.Rep as Profunctor
import Data.Profunctor.Unsafe
import Unsafe.Coerce
import Prelude hiding (foldl)

-- | A Moore Machine
data L a b = forall r. L (r -> b) (r -> a -> r) r

-- | Construct a Moore machine from a state valuation and transition function
unfoldL :: (s -> (b, a -> s)) -> s -> L a b
unfoldL :: (s -> (b, a -> s)) -> s -> L a b
unfoldL s -> (b, a -> s)
f = (s -> b) -> (s -> a -> s) -> s -> L a b
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L ((b, a -> s) -> b
forall a b. (a, b) -> a
fst ((b, a -> s) -> b) -> (s -> (b, a -> s)) -> s -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> (b, a -> s)
f) ((b, a -> s) -> a -> s
forall a b. (a, b) -> b
snd ((b, a -> s) -> a -> s) -> (s -> (b, a -> s)) -> s -> a -> s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> (b, a -> s)
f)
{-# INLINE unfoldL #-}

instance Scan L where
  run1 :: a -> L a b -> b
run1 a
t (L r -> b
k r -> a -> r
h r
z)    = r -> b
k (r -> a -> r
h r
z a
t)
  prefix1 :: a -> L a b -> L a b
prefix1 a
a           = a -> L a (L a b) -> L a b
forall (p :: * -> * -> *) a b. Scan p => a -> p a b -> b
run1 a
a (L a (L a b) -> L a b) -> (L a b -> L a (L a b)) -> L a b -> L a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. L a b -> L a (L a b)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate
  postfix1 :: L a b -> a -> L a b
postfix1 L a b
t a
a        = (L a b -> b) -> L a b -> L a b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (a -> L a b -> b
forall (p :: * -> * -> *) a b. Scan p => a -> p a b -> b
run1 a
a) L a b
t
  interspersing :: a -> L a b -> L a b
interspersing a
a (L r -> b
k r -> a -> r
h r
z) = (Maybe' r -> b) -> (Maybe' r -> a -> Maybe' r) -> Maybe' r -> L a b
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L (b -> (r -> b) -> Maybe' r -> b
forall b a. b -> (a -> b) -> Maybe' a -> b
maybe' (r -> b
k r
z) r -> b
k) Maybe' r -> a -> Maybe' r
h' Maybe' r
forall a. Maybe' a
Nothing' where
    h' :: Maybe' r -> a -> Maybe' r
h' Maybe' r
Nothing' a
b  = r -> Maybe' r
forall a. a -> Maybe' a
Just' (r -> a -> r
h r
z a
b)
    h' (Just' r
x) a
b = r -> Maybe' r
forall a. a -> Maybe' a
Just' (r -> a -> r
h (r -> a -> r
h r
x a
a) a
b)
  {-# INLINE run1 #-}
  {-# INLINE prefix1 #-}
  {-# INLINE postfix1 #-}
  {-# INLINE interspersing #-}

-- | efficient 'prefix', leaky 'postfix'
instance Folding L where
  run :: t a -> L a b -> b
run t a
t (L r -> b
k r -> a -> r
h r
z)     = r -> b
k ((r -> a -> r) -> r -> t a -> r
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl r -> a -> r
h r
z t a
t)
  runOf :: Fold s a -> s -> L a b -> b
runOf Fold s a
l s
s (L r -> b
k r -> a -> r
h r
z) = r -> b
k (Getting (Dual (Endo r)) s a -> (r -> a -> r) -> r -> s -> r
forall r s a.
Getting (Dual (Endo r)) s a -> (r -> a -> r) -> r -> s -> r
foldlOf Getting (Dual (Endo r)) s a
Fold s a
l r -> a -> r
h r
z s
s)
  prefix :: t a -> L a b -> L a b
prefix t a
s            = t a -> L a (L a b) -> L a b
forall (p :: * -> * -> *) (t :: * -> *) a b.
(Folding p, Foldable t) =>
t a -> p a b -> b
run t a
s (L a (L a b) -> L a b) -> (L a b -> L a (L a b)) -> L a b -> L a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. L a b -> L a (L a b)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate
  prefixOf :: Fold s a -> s -> L a b -> L a b
prefixOf Fold s a
l s
s        = Fold s a -> s -> L a (L a b) -> L a b
forall (p :: * -> * -> *) s a b.
Folding p =>
Fold s a -> s -> p a b -> b
runOf Fold s a
l s
s (L a (L a b) -> L a b) -> (L a b -> L a (L a b)) -> L a b -> L a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. L a b -> L a (L a b)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate
  postfix :: L a b -> t a -> L a b
postfix L a b
t t a
s         = (L a b -> b) -> L a b -> L a b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (t a -> L a b -> b
forall (p :: * -> * -> *) (t :: * -> *) a b.
(Folding p, Foldable t) =>
t a -> p a b -> b
run t a
s) L a b
t
  postfixOf :: Fold s a -> L a b -> s -> L a b
postfixOf Fold s a
l L a b
t s
s     = (L a b -> b) -> L a b -> L a b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (Fold s a -> s -> L a b -> b
forall (p :: * -> * -> *) s a b.
Folding p =>
Fold s a -> s -> p a b -> b
runOf Fold s a
l s
s) L a b
t
  filtering :: (a -> Bool) -> L a b -> L a b
filtering a -> Bool
p (L r -> b
k r -> a -> r
h r
z) = (r -> b) -> (r -> a -> r) -> r -> L a b
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L r -> b
k (\r
r a
a -> if a -> Bool
p a
a then r -> a -> r
h r
r a
a else r
r) r
z
  {-# INLINE run #-}
  {-# INLINE runOf #-}
  {-# INLINE prefix #-}
  {-# INLINE prefixOf #-}
  {-# INLINE postfix #-}
  {-# INLINE postfixOf #-}
  {-# INLINE filtering #-}

{-
enscanl s (L k h z) = snd (mapAccumL h' z s) where
  h' r a = (r', k r') where r' = h r a

enscanlOf l s (L k h z) = snd (mapAccumLOf l h' z s) where
  h' r a = (r', k r') where r' = h r a
-}

instance Profunctor L where
  dimap :: (a -> b) -> (c -> d) -> L b c -> L a d
dimap a -> b
f c -> d
g (L r -> c
k r -> b -> r
h r
z) = (r -> d) -> (r -> a -> r) -> r -> L a d
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L (c -> d
g(c -> d) -> (r -> c) -> r -> d
forall b c a. (b -> c) -> (a -> b) -> a -> c
.r -> c
k) (\r
r -> r -> b -> r
h r
r (b -> r) -> (a -> b) -> a -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) r
z
  {-# INLINE dimap #-}
  rmap :: (b -> c) -> L a b -> L a c
rmap b -> c
g (L r -> b
k r -> a -> r
h r
z) = (r -> c) -> (r -> a -> r) -> r -> L a c
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L (b -> c
g(b -> c) -> (r -> b) -> r -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
.r -> b
k) r -> a -> r
h r
z
  {-# INLINE rmap #-}
  lmap :: (a -> b) -> L b c -> L a c
lmap a -> b
f (L r -> c
k r -> b -> r
h r
z) = (r -> c) -> (r -> a -> r) -> r -> L a c
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L r -> c
k (\r
r -> r -> b -> r
h r
r (b -> r) -> (a -> b) -> a -> r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) r
z
  {-# INLINE lmap #-}
  #. :: q b c -> L a b -> L a c
(#.) q b c
_ = L a b -> L a c
forall a b. a -> b
unsafeCoerce
  {-# INLINE (#.) #-}
  L b c
x .# :: L b c -> q a b -> L a c
.# q a b
_ = L b c -> L a c
forall a b. a -> b
unsafeCoerce L b c
x
  {-# INLINE (.#) #-}

instance Choice L where
  left' :: L a b -> L (Either a c) (Either b c)
left' (L r -> b
k r -> a -> r
h r
z) = (Either r c -> Either b c)
-> (Either r c -> Either a c -> Either r c)
-> Either r c
-> L (Either a c) (Either b c)
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L ((r -> Identity b) -> Either r c -> Identity (Either b c)
forall a c b. Prism (Either a c) (Either b c) a b
_Left ((r -> Identity b) -> Either r c -> Identity (Either b c))
-> (r -> b) -> Either r c -> Either b c
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ r -> b
k) Either r c -> Either a c -> Either r c
step (r -> Either r c
forall a b. a -> Either a b
Left r
z) where
    step :: Either r c -> Either a c -> Either r c
step (Left r
x) (Left a
y) = r -> Either r c
forall a b. a -> Either a b
Left (r -> a -> r
h r
x a
y)
    step (Right c
c) Either a c
_ = c -> Either r c
forall a b. b -> Either a b
Right c
c
    step Either r c
_ (Right c
c) = c -> Either r c
forall a b. b -> Either a b
Right c
c
  {-# INLINE left' #-}

  right' :: L a b -> L (Either c a) (Either c b)
right' (L r -> b
k r -> a -> r
h r
z) = (Either c r -> Either c b)
-> (Either c r -> Either c a -> Either c r)
-> Either c r
-> L (Either c a) (Either c b)
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L ((r -> Identity b) -> Either c r -> Identity (Either c b)
forall c a b. Prism (Either c a) (Either c b) a b
_Right ((r -> Identity b) -> Either c r -> Identity (Either c b))
-> (r -> b) -> Either c r -> Either c b
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ r -> b
k) Either c r -> Either c a -> Either c r
step (r -> Either c r
forall a b. b -> Either a b
Right r
z) where
    step :: Either c r -> Either c a -> Either c r
step (Right r
x) (Right a
y) = r -> Either c r
forall a b. b -> Either a b
Right (r -> a -> r
h r
x a
y)
    step (Left c
c) Either c a
_ = c -> Either c r
forall a b. a -> Either a b
Left c
c
    step Either c r
_ (Left c
c) = c -> Either c r
forall a b. a -> Either a b
Left c
c
  {-# INLINE right' #-}

instance Functor (L a) where
  fmap :: (a -> b) -> L a a -> L a b
fmap a -> b
f (L r -> a
k r -> a -> r
h r
z) = (r -> b) -> (r -> a -> r) -> r -> L a b
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L (a -> b
f(a -> b) -> (r -> a) -> r -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
.r -> a
k) r -> a -> r
h r
z
  {-# INLINE fmap #-}

  <$ :: a -> L a b -> L a a
(<$) a
b = \L a b
_ -> a -> L a a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
b
  {-# INLINE (<$) #-}

instance Comonad (L a) where
  extract :: L a a -> a
extract (L r -> a
k r -> a -> r
_ r
z) = r -> a
k r
z
  {-# INLINE extract #-}

  duplicate :: L a a -> L a (L a a)
duplicate (L r -> a
k r -> a -> r
h r
z) = (r -> L a a) -> (r -> a -> r) -> r -> L a (L a a)
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L ((r -> a) -> (r -> a -> r) -> r -> L a a
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L r -> a
k r -> a -> r
h) r -> a -> r
h r
z
  {-# INLINE duplicate #-}

  extend :: (L a a -> b) -> L a a -> L a b
extend L a a -> b
f (L r -> a
k r -> a -> r
h r
z)  = (r -> b) -> (r -> a -> r) -> r -> L a b
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L (L a a -> b
f (L a a -> b) -> (r -> L a a) -> r -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (r -> a) -> (r -> a -> r) -> r -> L a a
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L r -> a
k r -> a -> r
h) r -> a -> r
h r
z
  {-# INLINE extend #-}

instance Applicative (L a) where
  pure :: a -> L a a
pure a
b = (() -> a) -> (() -> a -> ()) -> () -> L a a
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L (\() -> a
b) (\() a
_ -> ()) ()
  {-# INLINE pure #-}

  L r -> a -> b
xf r -> a -> r
bxx r
xz <*> :: L a (a -> b) -> L a a -> L a b
<*> L r -> a
ya r -> a -> r
byy r
yz = (Pair' r r -> b)
-> (Pair' r r -> a -> Pair' r r) -> Pair' r r -> L a b
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L
    (\(Pair' r
x r
y) -> r -> a -> b
xf r
x (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ r -> a
ya r
y)
    (\(Pair' r
x r
y) a
b -> r -> r -> Pair' r r
forall a b. a -> b -> Pair' a b
Pair' (r -> a -> r
bxx r
x a
b) (r -> a -> r
byy r
y a
b))
    (r -> r -> Pair' r r
forall a b. a -> b -> Pair' a b
Pair' r
xz r
yz)
  {-# INLINE (<*>) #-}

  <* :: L a a -> L a b -> L a a
(<*) L a a
m = \L a b
_ -> L a a
m
  {-# INLINE (<*) #-}

  L a a
_ *> :: L a a -> L a b -> L a b
*> L a b
m = L a b
m
  {-# INLINE (*>) #-}

instance Bind (L a) where
  >>- :: L a a -> (a -> L a b) -> L a b
(>>-) = L a a -> (a -> L a b) -> L a b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
(>>=)
  {-# INLINE (>>-) #-}

instance Monad (L a) where
  return :: a -> L a a
return = a -> L a a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  {-# INLINE return #-}

  L a a
m >>= :: L a a -> (a -> L a b) -> L a b
>>= a -> L a b
f = (SnocList a -> a -> b)
-> (SnocList a -> a -> SnocList a) -> SnocList a -> L a (a -> b)
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L (\SnocList a
xs a
a -> SnocList a -> L a b -> b
forall (p :: * -> * -> *) (t :: * -> *) a b.
(Folding p, Foldable t) =>
t a -> p a b -> b
run SnocList a
xs (a -> L a b
f a
a)) SnocList a -> a -> SnocList a
forall a. SnocList a -> a -> SnocList a
Snoc SnocList a
forall a. SnocList a
Nil L a (a -> b) -> L a a -> L a b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> L a a
m
  {-# INLINE (>>=) #-}

  >> :: L a a -> L a b -> L a b
(>>) = L a a -> L a b -> L a b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)
  {-# INLINE (>>) #-}

instance MonadZip (L a) where
  mzipWith :: (a -> b -> c) -> L a a -> L a b -> L a c
mzipWith = (a -> b -> c) -> L a a -> L a b -> L a c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
  {-# INLINE mzipWith #-}

instance Extend (L a) where
  extended :: (L a a -> b) -> L a a -> L a b
extended = (L a a -> b) -> L a a -> L a b
forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend
  {-# INLINE extended #-}

  duplicated :: L a a -> L a (L a a)
duplicated = L a a -> L a (L a a)
forall (w :: * -> *) a. Comonad w => w a -> w (w a)
duplicate
  {-# INLINE duplicated #-}

instance Apply (L a) where
  <.> :: L a (a -> b) -> L a a -> L a b
(<.>) = L a (a -> b) -> L a a -> L a b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
  {-# INLINE (<.>) #-}

  <. :: L a a -> L a b -> L a a
(<.) L a a
m = \L a b
_ -> L a a
m
  {-# INLINE (<.) #-}

  L a a
_ .> :: L a a -> L a b -> L a b
.> L a b
m = L a b
m
  {-# INLINE (.>) #-}

instance ComonadApply (L a) where
  <@> :: L a (a -> b) -> L a a -> L a b
(<@>) = L a (a -> b) -> L a a -> L a b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
  {-# INLINE (<@>) #-}

  <@ :: L a a -> L a b -> L a a
(<@) L a a
m = \L a b
_ -> L a a
m
  {-# INLINE (<@) #-}

  L a a
_ @> :: L a a -> L a b -> L a b
@> L a b
m = L a b
m
  {-# INLINE (@>) #-}

instance Distributive (L a) where
  distribute :: f (L a a) -> L a (f a)
distribute = (f (L a a) -> f a)
-> (f (L a a) -> a -> f (L a a)) -> f (L a a) -> L a (f a)
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L ((L a a -> a) -> f (L a a) -> f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap L a a -> a
forall (w :: * -> *) a. Comonad w => w a -> a
extract) (\f (L a a)
fm a
a -> (L a a -> L a a) -> f (L a a) -> f (L a a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> L a a -> L a a
forall (p :: * -> * -> *) a b. Scan p => a -> p a b -> p a b
prefix1 a
a) f (L a a)
fm)
  {-# INLINE distribute #-}

instance Functor.Representable (L a) where
  type Rep (L a) = [a]
  index :: L a a -> Rep (L a) -> a
index = L a a -> Rep (L a) -> a
forall (p :: * -> * -> *) (f :: * -> *) a b.
Cosieve p f =>
p a b -> f a -> b
cosieve
  tabulate :: (Rep (L a) -> a) -> L a a
tabulate = (Rep (L a) -> a) -> L a a
forall (p :: * -> * -> *) d c.
Corepresentable p =>
(Corep p d -> c) -> p d c
cotabulate

instance MonadReader [a] (L a) where
  ask :: L a [a]
ask = L a [a]
forall (f :: * -> *). Representable f => f (Rep f)
askRep
  local :: ([a] -> [a]) -> L a a -> L a a
local = ([a] -> [a]) -> L a a -> L a a
forall (f :: * -> *) a.
Representable f =>
(Rep f -> Rep f) -> f a -> f a
localRep

instance Costrong L where
  unfirst :: L (a, d) (b, d) -> L a b
unfirst = L (a, d) (b, d) -> L a b
forall (p :: * -> * -> *) a d b.
Corepresentable p =>
p (a, d) (b, d) -> p a b
unfirstCorep
  unsecond :: L (d, a) (d, b) -> L a b
unsecond = L (d, a) (d, b) -> L a b
forall (p :: * -> * -> *) d a b.
Corepresentable p =>
p (d, a) (d, b) -> p a b
unsecondCorep

-- | >>> cosieve (L id (+) 0) [1,2,3]
-- 6

instance Cosieve L [] where
  cosieve :: L a b -> [a] -> b
cosieve (L r -> b
k0 r -> a -> r
h0 r
z0) [a]
as0 = (r -> b) -> (r -> a -> r) -> r -> [a] -> b
forall t p t. (t -> p) -> (t -> t -> t) -> t -> [t] -> p
go r -> b
k0 r -> a -> r
h0 r
z0 [a]
as0 where
    go :: (t -> p) -> (t -> t -> t) -> t -> [t] -> p
go t -> p
k t -> t -> t
_ t
z [] = t -> p
k t
z
    go t -> p
k t -> t -> t
h t
z (t
a:[t]
as) = (t -> p) -> (t -> t -> t) -> t -> [t] -> p
go t -> p
k t -> t -> t
h (t -> t -> t
h t
z t
a) [t]
as
  {-# INLINE cosieve #-}

instance Closed L where
  closed :: L a b -> L (x -> a) (x -> b)
closed (L r -> b
k r -> a -> r
h r
z) = ((x -> r) -> x -> b)
-> ((x -> r) -> (x -> a) -> x -> r)
-> (x -> r)
-> L (x -> a) (x -> b)
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L (\x -> r
f x
x -> r -> b
k (x -> r
f x
x)) ((r -> a -> r) -> (x -> r) -> (x -> a) -> x -> r
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 r -> a -> r
h) (r -> x -> r
forall (f :: * -> *) a. Applicative f => a -> f a
pure r
z)

instance Profunctor.Corepresentable L where
  type Corep L = []
  cotabulate :: (Corep L d -> c) -> L d c
cotabulate Corep L d -> c
f = ([d] -> c) -> ([d] -> d -> [d]) -> [d] -> L d c
forall a b r. (r -> b) -> (r -> a -> r) -> r -> L a b
L ([d] -> c
Corep L d -> c
f ([d] -> c) -> ([d] -> [d]) -> [d] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [d] -> [d]
forall a. [a] -> [a]
reverse) ((d -> [d] -> [d]) -> [d] -> d -> [d]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (:)) []
  {-# INLINE cotabulate #-}

instance MonadFix (L a) where
  mfix :: (a -> L a a) -> L a a
mfix = (a -> L a a) -> L a a
forall (f :: * -> *) a. Representable f => (a -> f a) -> f a
mfixRep