{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE StandaloneDeriving #-}
module Control.Comonad.Trans.Coiter
(
CoiterT(..)
, Coiter, coiter, runCoiter
, unfold
, ComonadCofree(..)
) where
import Control.Arrow hiding (second)
import Control.Comonad
import Control.Comonad.Cofree.Class
import Control.Comonad.Env.Class
import Control.Comonad.Hoist.Class
import Control.Comonad.Store.Class
import Control.Comonad.Traced.Class
import Control.Comonad.Trans.Class
import Control.Category
import Data.Bifunctor
import Data.Bifoldable
import Data.Bitraversable
import Data.Data
import Data.Foldable
import Data.Functor.Classes
import Data.Functor.Identity
import Data.Traversable
import Prelude hiding (id,(.))
newtype CoiterT w a = CoiterT { forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT :: w (a, CoiterT w a) }
instance (Eq1 w) => Eq1 (CoiterT w) where
liftEq :: forall a b. (a -> b -> Bool) -> CoiterT w a -> CoiterT w b -> Bool
liftEq a -> b -> Bool
eq = forall {f :: * -> *}. Eq1 f => CoiterT f a -> CoiterT f b -> Bool
go
where
go :: CoiterT f a -> CoiterT f b -> Bool
go (CoiterT f (a, CoiterT f a)
x) (CoiterT f (b, CoiterT f b)
y) = forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq (forall (f :: * -> * -> *) a b c d.
Eq2 f =>
(a -> b -> Bool) -> (c -> d -> Bool) -> f a c -> f b d -> Bool
liftEq2 a -> b -> Bool
eq CoiterT f a -> CoiterT f b -> Bool
go) f (a, CoiterT f a)
x f (b, CoiterT f b)
y
instance (Ord1 w) => Ord1 (CoiterT w) where
liftCompare :: forall a b.
(a -> b -> Ordering) -> CoiterT w a -> CoiterT w b -> Ordering
liftCompare a -> b -> Ordering
cmp = forall {f :: * -> *}.
Ord1 f =>
CoiterT f a -> CoiterT f b -> Ordering
go
where
go :: CoiterT f a -> CoiterT f b -> Ordering
go (CoiterT f (a, CoiterT f a)
x) (CoiterT f (b, CoiterT f b)
y) = forall (f :: * -> *) a b.
Ord1 f =>
(a -> b -> Ordering) -> f a -> f b -> Ordering
liftCompare (forall (f :: * -> * -> *) a b c d.
Ord2 f =>
(a -> b -> Ordering)
-> (c -> d -> Ordering) -> f a c -> f b d -> Ordering
liftCompare2 a -> b -> Ordering
cmp CoiterT f a -> CoiterT f b -> Ordering
go) f (a, CoiterT f a)
x f (b, CoiterT f b)
y
instance (Show1 w) => Show1 (CoiterT w) where
liftShowsPrec :: forall a.
(Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> CoiterT w a -> ShowS
liftShowsPrec Int -> a -> ShowS
sp [a] -> ShowS
sl = Int -> CoiterT w a -> ShowS
go
where
goList :: [CoiterT w a] -> ShowS
goList = forall (f :: * -> *) a.
Show1 f =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [f a] -> ShowS
liftShowList Int -> a -> ShowS
sp [a] -> ShowS
sl
go :: Int -> CoiterT w a -> ShowS
go Int
d (CoiterT w (a, CoiterT w a)
x) = forall a. (Int -> a -> ShowS) -> String -> Int -> a -> ShowS
showsUnaryWith
(forall (f :: * -> *) a.
Show1 f =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS
liftShowsPrec (forall (f :: * -> * -> *) a b.
Show2 f =>
(Int -> a -> ShowS)
-> ([a] -> ShowS)
-> (Int -> b -> ShowS)
-> ([b] -> ShowS)
-> Int
-> f a b
-> ShowS
liftShowsPrec2 Int -> a -> ShowS
sp [a] -> ShowS
sl Int -> CoiterT w a -> ShowS
go [CoiterT w a] -> ShowS
goList) (forall (f :: * -> * -> *) a b.
Show2 f =>
(Int -> a -> ShowS)
-> ([a] -> ShowS)
-> (Int -> b -> ShowS)
-> ([b] -> ShowS)
-> [f a b]
-> ShowS
liftShowList2 Int -> a -> ShowS
sp [a] -> ShowS
sl Int -> CoiterT w a -> ShowS
go [CoiterT w a] -> ShowS
goList))
String
"CoiterT" Int
d w (a, CoiterT w a)
x
instance (Read1 w) => Read1 (CoiterT w) where
liftReadsPrec :: forall a.
(Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (CoiterT w a)
liftReadsPrec Int -> ReadS a
rp ReadS [a]
rl = Int -> ReadS (CoiterT w a)
go
where
goList :: ReadS [CoiterT w a]
goList = forall (f :: * -> *) a.
Read1 f =>
(Int -> ReadS a) -> ReadS [a] -> ReadS [f a]
liftReadList Int -> ReadS a
rp ReadS [a]
rl
go :: Int -> ReadS (CoiterT w a)
go = forall a. (String -> ReadS a) -> Int -> ReadS a
readsData forall a b. (a -> b) -> a -> b
$ forall a t.
(Int -> ReadS a) -> String -> (a -> t) -> String -> ReadS t
readsUnaryWith
(forall (f :: * -> *) a.
Read1 f =>
(Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (f a)
liftReadsPrec (forall (f :: * -> * -> *) a b.
Read2 f =>
(Int -> ReadS a)
-> ReadS [a]
-> (Int -> ReadS b)
-> ReadS [b]
-> Int
-> ReadS (f a b)
liftReadsPrec2 Int -> ReadS a
rp ReadS [a]
rl Int -> ReadS (CoiterT w a)
go ReadS [CoiterT w a]
goList) (forall (f :: * -> * -> *) a b.
Read2 f =>
(Int -> ReadS a)
-> ReadS [a] -> (Int -> ReadS b) -> ReadS [b] -> ReadS [f a b]
liftReadList2 Int -> ReadS a
rp ReadS [a]
rl Int -> ReadS (CoiterT w a)
go ReadS [CoiterT w a]
goList))
String
"CoiterT" forall (w :: * -> *) a. w (a, CoiterT w a) -> CoiterT w a
CoiterT
type Coiter = CoiterT Identity
coiter :: a -> Coiter a -> Coiter a
coiter :: forall a. a -> Coiter a -> Coiter a
coiter a
a Coiter a
as = forall (w :: * -> *) a. w (a, CoiterT w a) -> CoiterT w a
CoiterT forall a b. (a -> b) -> a -> b
$ forall a. a -> Identity a
Identity (a
a,Coiter a
as)
{-# INLINE coiter #-}
runCoiter :: Coiter a -> (a, Coiter a)
runCoiter :: forall a. Coiter a -> (a, Coiter a)
runCoiter = forall a. Identity a -> a
runIdentity forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
{-# INLINE runCoiter #-}
instance Functor w => Functor (CoiterT w) where
fmap :: forall a b. (a -> b) -> CoiterT w a -> CoiterT w b
fmap a -> b
f = forall (w :: * -> *) a. w (a, CoiterT w a) -> CoiterT w a
CoiterT forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> b
f (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f)) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
instance Comonad w => Comonad (CoiterT w) where
extract :: forall a. CoiterT w a -> a
extract = forall a b. (a, b) -> a
fst forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. Comonad w => w a -> a
extract forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
{-# INLINE extract #-}
extend :: forall a b. (CoiterT w a -> b) -> CoiterT w a -> CoiterT w b
extend CoiterT w a -> b
f = forall (w :: * -> *) a. w (a, CoiterT w a) -> CoiterT w a
CoiterT forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (\w (a, CoiterT w a)
w -> (CoiterT w a -> b
f (forall (w :: * -> *) a. w (a, CoiterT w a) -> CoiterT w a
CoiterT w (a, CoiterT w a)
w), forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend CoiterT w a -> b
f forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ forall (w :: * -> *) a. Comonad w => w a -> a
extract w (a, CoiterT w a)
w)) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
instance Foldable w => Foldable (CoiterT w) where
foldMap :: forall m a. Monoid m => (a -> m) -> CoiterT w a -> m
foldMap a -> m
f = forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (forall (p :: * -> * -> *) m a b.
(Bifoldable p, Monoid m) =>
(a -> m) -> (b -> m) -> p a b -> m
bifoldMap a -> m
f (forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f)) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
instance Traversable w => Traversable (CoiterT w) where
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CoiterT w a -> f (CoiterT w b)
traverse a -> f b
f = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (w :: * -> *) a. w (a, CoiterT w a) -> CoiterT w a
CoiterT forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (forall (t :: * -> * -> *) (f :: * -> *) a c b d.
(Bitraversable t, Applicative f) =>
(a -> f c) -> (b -> f d) -> t a b -> f (t c d)
bitraverse a -> f b
f (forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> f b
f)) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
instance ComonadTrans CoiterT where
lower :: forall (w :: * -> *) a. Comonad w => CoiterT w a -> w a
lower = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
instance Comonad w => ComonadCofree Identity (CoiterT w) where
unwrap :: forall a. CoiterT w a -> Identity (CoiterT w a)
unwrap = forall a. a -> Identity a
Identity forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a b. (a, b) -> b
snd forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. Comonad w => w a -> a
extract forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
{-# INLINE unwrap #-}
instance ComonadEnv e w => ComonadEnv e (CoiterT w) where
ask :: forall a. CoiterT w a -> e
ask = forall e (w :: * -> *) a. ComonadEnv e w => w a -> e
ask forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> *) -> * -> *) (w :: * -> *) a.
(ComonadTrans t, Comonad w) =>
t w a -> w a
lower
{-# INLINE ask #-}
instance ComonadHoist CoiterT where
cohoist :: forall (w :: * -> *) (v :: * -> *) a.
(Comonad w, Comonad v) =>
(forall x. w x -> v x) -> CoiterT w a -> CoiterT v a
cohoist forall x. w x -> v x
g = forall (w :: * -> *) a. w (a, CoiterT w a) -> CoiterT w a
CoiterT forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (forall (t :: (* -> *) -> * -> *) (w :: * -> *) (v :: * -> *) a.
(ComonadHoist t, Comonad w, Comonad v) =>
(forall x. w x -> v x) -> t w a -> t v a
cohoist forall x. w x -> v x
g)) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall x. w x -> v x
g forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a. CoiterT w a -> w (a, CoiterT w a)
runCoiterT
instance ComonadTraced m w => ComonadTraced m (CoiterT w) where
trace :: forall a. m -> CoiterT w a -> a
trace m
m = forall m (w :: * -> *) a. ComonadTraced m w => m -> w a -> a
trace m
m forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> *) -> * -> *) (w :: * -> *) a.
(ComonadTrans t, Comonad w) =>
t w a -> w a
lower
{-# INLINE trace #-}
instance ComonadStore s w => ComonadStore s (CoiterT w) where
pos :: forall a. CoiterT w a -> s
pos = forall s (w :: * -> *) a. ComonadStore s w => w a -> s
pos forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> *) -> * -> *) (w :: * -> *) a.
(ComonadTrans t, Comonad w) =>
t w a -> w a
lower
peek :: forall a. s -> CoiterT w a -> a
peek s
s = forall s (w :: * -> *) a. ComonadStore s w => s -> w a -> a
peek s
s forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> *) -> * -> *) (w :: * -> *) a.
(ComonadTrans t, Comonad w) =>
t w a -> w a
lower
peeks :: forall a. (s -> s) -> CoiterT w a -> a
peeks s -> s
f = forall s (w :: * -> *) a. ComonadStore s w => (s -> s) -> w a -> a
peeks s -> s
f forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> *) -> * -> *) (w :: * -> *) a.
(ComonadTrans t, Comonad w) =>
t w a -> w a
lower
seek :: forall a. s -> CoiterT w a -> CoiterT w a
seek = forall s (w :: * -> *) a. ComonadStore s w => s -> w a -> w a
seek
seeks :: forall a. (s -> s) -> CoiterT w a -> CoiterT w a
seeks = forall s (w :: * -> *) a.
ComonadStore s w =>
(s -> s) -> w a -> w a
seeks
experiment :: forall (f :: * -> *) a.
Functor f =>
(s -> f s) -> CoiterT w a -> f a
experiment s -> f s
f = forall s (w :: * -> *) (f :: * -> *) a.
(ComonadStore s w, Functor f) =>
(s -> f s) -> w a -> f a
experiment s -> f s
f forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> *) -> * -> *) (w :: * -> *) a.
(ComonadTrans t, Comonad w) =>
t w a -> w a
lower
{-# INLINE pos #-}
{-# INLINE peek #-}
{-# INLINE peeks #-}
{-# INLINE seek #-}
{-# INLINE seeks #-}
{-# INLINE experiment #-}
instance (Show1 w, Show a) => Show (CoiterT w a) where
showsPrec :: Int -> CoiterT w a -> ShowS
showsPrec = forall (f :: * -> *) a. (Show1 f, Show a) => Int -> f a -> ShowS
showsPrec1
instance (Read1 w, Read a) => Read (CoiterT w a) where
readsPrec :: Int -> ReadS (CoiterT w a)
readsPrec = forall (f :: * -> *) a. (Read1 f, Read a) => Int -> ReadS (f a)
readsPrec1
instance (Eq1 w, Eq a) => Eq (CoiterT w a) where
== :: CoiterT w a -> CoiterT w a -> Bool
(==) = forall (f :: * -> *) a. (Eq1 f, Eq a) => f a -> f a -> Bool
eq1
{-# INLINE (==) #-}
instance (Ord1 w, Ord a) => Ord (CoiterT w a) where
compare :: CoiterT w a -> CoiterT w a -> Ordering
compare = forall (f :: * -> *) a. (Ord1 f, Ord a) => f a -> f a -> Ordering
compare1
{-# INLINE compare #-}
unfold :: Comonad w => (w a -> a) -> w a -> CoiterT w a
unfold :: forall (w :: * -> *) a.
Comonad w =>
(w a -> a) -> w a -> CoiterT w a
unfold w a -> a
psi = forall (w :: * -> *) a. w (a, CoiterT w a) -> CoiterT w a
CoiterT forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend (forall (w :: * -> *) a. Comonad w => w a -> a
extract forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& forall (w :: * -> *) a.
Comonad w =>
(w a -> a) -> w a -> CoiterT w a
unfold w a -> a
psi forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend w a -> a
psi)
deriving instance
( Typeable w
, Data (w (a, CoiterT w a))
, Data a
) => Data (CoiterT w a)