{-# LANGUAGE TypeSynonymInstances, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, Safe #-}
module Data.Chatty.ListBuilder where
import Control.Applicative
import Control.Arrow
import Control.Monad.Trans.Class
import Control.Monad.Identity
class Monad l => ListBuilder l i | l -> i where
li :: i -> l ()
buildList :: l () -> [i]
newtype StrictBuilderT i m a = StrictBuilder { StrictBuilderT i m a -> [i] -> m (a, [i])
runStrictBuilderT :: [i] -> m (a,[i]) }
type StrictBuilder i = StrictBuilderT i Identity
instance Functor m => Functor (StrictBuilderT i m) where
fmap :: (a -> b) -> StrictBuilderT i m a -> StrictBuilderT i m b
fmap a -> b
f StrictBuilderT i m a
a = ([i] -> m (b, [i])) -> StrictBuilderT i m b
forall i (m :: * -> *) a.
([i] -> m (a, [i])) -> StrictBuilderT i m a
StrictBuilder (([i] -> m (b, [i])) -> StrictBuilderT i m b)
-> ([i] -> m (b, [i])) -> StrictBuilderT i m b
forall a b. (a -> b) -> a -> b
$ \[i]
s -> ((a, [i]) -> (b, [i])) -> m (a, [i]) -> m (b, [i])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> (a, [i]) -> (b, [i])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first a -> b
f) (m (a, [i]) -> m (b, [i])) -> m (a, [i]) -> m (b, [i])
forall a b. (a -> b) -> a -> b
$ StrictBuilderT i m a -> [i] -> m (a, [i])
forall i (m :: * -> *) a. StrictBuilderT i m a -> [i] -> m (a, [i])
runStrictBuilderT StrictBuilderT i m a
a [i]
s
instance (Functor m, Monad m) => Applicative (StrictBuilderT i m) where
<*> :: StrictBuilderT i m (a -> b)
-> StrictBuilderT i m a -> StrictBuilderT i m b
(<*>) = StrictBuilderT i m (a -> b)
-> StrictBuilderT i m a -> StrictBuilderT i m b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
pure :: a -> StrictBuilderT i m a
pure = a -> StrictBuilderT i m a
forall (m :: * -> *) a. Monad m => a -> m a
return
instance Monad m => Monad (StrictBuilderT i m) where
return :: a -> StrictBuilderT i m a
return a
a = ([i] -> m (a, [i])) -> StrictBuilderT i m a
forall i (m :: * -> *) a.
([i] -> m (a, [i])) -> StrictBuilderT i m a
StrictBuilder (([i] -> m (a, [i])) -> StrictBuilderT i m a)
-> ([i] -> m (a, [i])) -> StrictBuilderT i m a
forall a b. (a -> b) -> a -> b
$ \[i]
s -> (a, [i]) -> m (a, [i])
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,[i]
s)
StrictBuilderT i m a
m >>= :: StrictBuilderT i m a
-> (a -> StrictBuilderT i m b) -> StrictBuilderT i m b
>>= a -> StrictBuilderT i m b
f = ([i] -> m (b, [i])) -> StrictBuilderT i m b
forall i (m :: * -> *) a.
([i] -> m (a, [i])) -> StrictBuilderT i m a
StrictBuilder (([i] -> m (b, [i])) -> StrictBuilderT i m b)
-> ([i] -> m (b, [i])) -> StrictBuilderT i m b
forall a b. (a -> b) -> a -> b
$ \[i]
s -> do (a
a,[i]
s') <- StrictBuilderT i m a -> [i] -> m (a, [i])
forall i (m :: * -> *) a. StrictBuilderT i m a -> [i] -> m (a, [i])
runStrictBuilderT StrictBuilderT i m a
m [i]
s; StrictBuilderT i m b -> [i] -> m (b, [i])
forall i (m :: * -> *) a. StrictBuilderT i m a -> [i] -> m (a, [i])
runStrictBuilderT (a -> StrictBuilderT i m b
f a
a) [i]
s'
instance MonadTrans (StrictBuilderT i) where
lift :: m a -> StrictBuilderT i m a
lift m a
m = ([i] -> m (a, [i])) -> StrictBuilderT i m a
forall i (m :: * -> *) a.
([i] -> m (a, [i])) -> StrictBuilderT i m a
StrictBuilder (([i] -> m (a, [i])) -> StrictBuilderT i m a)
-> ([i] -> m (a, [i])) -> StrictBuilderT i m a
forall a b. (a -> b) -> a -> b
$ \[i]
s -> do a
a <- m a
m; (a, [i]) -> m (a, [i])
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,[i]
s)
instance ListBuilder (StrictBuilder i) i where
li :: i -> StrictBuilder i ()
li i
a = i -> StrictBuilder i () -> StrictBuilder i ()
seq i
a (StrictBuilder i () -> StrictBuilder i ())
-> StrictBuilder i () -> StrictBuilder i ()
forall a b. (a -> b) -> a -> b
$ ([i] -> Identity ((), [i])) -> StrictBuilder i ()
forall i (m :: * -> *) a.
([i] -> m (a, [i])) -> StrictBuilderT i m a
StrictBuilder (([i] -> Identity ((), [i])) -> StrictBuilder i ())
-> ([i] -> Identity ((), [i])) -> StrictBuilder i ()
forall a b. (a -> b) -> a -> b
$ \[i]
s -> ((), [i]) -> Identity ((), [i])
forall (m :: * -> *) a. Monad m => a -> m a
return ((),[i]
s[i] -> [i] -> [i]
forall a. [a] -> [a] -> [a]
++[i
a])
buildList :: StrictBuilder i () -> [i]
buildList StrictBuilder i ()
m = ((), [i]) -> [i]
forall a b. (a, b) -> b
snd (((), [i]) -> [i]) -> ((), [i]) -> [i]
forall a b. (a -> b) -> a -> b
$ Identity ((), [i]) -> ((), [i])
forall a. Identity a -> a
runIdentity (Identity ((), [i]) -> ((), [i]))
-> Identity ((), [i]) -> ((), [i])
forall a b. (a -> b) -> a -> b
$ StrictBuilder i () -> [i] -> Identity ((), [i])
forall i (m :: * -> *) a. StrictBuilderT i m a -> [i] -> m (a, [i])
runStrictBuilderT StrictBuilder i ()
m []
strictBuild :: StrictBuilderT i Identity () -> [i]
strictBuild :: StrictBuilderT i Identity () -> [i]
strictBuild = StrictBuilderT i Identity () -> [i]
forall (l :: * -> *) i. ListBuilder l i => l () -> [i]
buildList
newtype LazyBuilderT i m a = LazyBuilder { LazyBuilderT i m a -> ([i] -> [i]) -> m (a, [i] -> [i])
runLazyBuilderT :: ([i] -> [i]) -> m (a,[i] -> [i]) }
type LazyBuilder i = LazyBuilderT i Identity
instance Functor m => Functor (LazyBuilderT i m) where
fmap :: (a -> b) -> LazyBuilderT i m a -> LazyBuilderT i m b
fmap a -> b
f LazyBuilderT i m a
a = (([i] -> [i]) -> m (b, [i] -> [i])) -> LazyBuilderT i m b
forall i (m :: * -> *) a.
(([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
LazyBuilder ((([i] -> [i]) -> m (b, [i] -> [i])) -> LazyBuilderT i m b)
-> (([i] -> [i]) -> m (b, [i] -> [i])) -> LazyBuilderT i m b
forall a b. (a -> b) -> a -> b
$ \[i] -> [i]
s -> ((a, [i] -> [i]) -> (b, [i] -> [i]))
-> m (a, [i] -> [i]) -> m (b, [i] -> [i])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> (a, [i] -> [i]) -> (b, [i] -> [i])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first a -> b
f) (m (a, [i] -> [i]) -> m (b, [i] -> [i]))
-> m (a, [i] -> [i]) -> m (b, [i] -> [i])
forall a b. (a -> b) -> a -> b
$ LazyBuilderT i m a -> ([i] -> [i]) -> m (a, [i] -> [i])
forall i (m :: * -> *) a.
LazyBuilderT i m a -> ([i] -> [i]) -> m (a, [i] -> [i])
runLazyBuilderT LazyBuilderT i m a
a [i] -> [i]
s
instance (Functor m,Monad m) => Applicative (LazyBuilderT i m) where
pure :: a -> LazyBuilderT i m a
pure = a -> LazyBuilderT i m a
forall (m :: * -> *) a. Monad m => a -> m a
return
<*> :: LazyBuilderT i m (a -> b)
-> LazyBuilderT i m a -> LazyBuilderT i m b
(<*>) = LazyBuilderT i m (a -> b)
-> LazyBuilderT i m a -> LazyBuilderT i m b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
instance Monad m => Monad (LazyBuilderT i m) where
return :: a -> LazyBuilderT i m a
return a
a = (([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
forall i (m :: * -> *) a.
(([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
LazyBuilder ((([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a)
-> (([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
forall a b. (a -> b) -> a -> b
$ \[i] -> [i]
s -> (a, [i] -> [i]) -> m (a, [i] -> [i])
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,[i] -> [i]
s)
LazyBuilderT i m a
m >>= :: LazyBuilderT i m a
-> (a -> LazyBuilderT i m b) -> LazyBuilderT i m b
>>= a -> LazyBuilderT i m b
f = (([i] -> [i]) -> m (b, [i] -> [i])) -> LazyBuilderT i m b
forall i (m :: * -> *) a.
(([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
LazyBuilder ((([i] -> [i]) -> m (b, [i] -> [i])) -> LazyBuilderT i m b)
-> (([i] -> [i]) -> m (b, [i] -> [i])) -> LazyBuilderT i m b
forall a b. (a -> b) -> a -> b
$ \[i] -> [i]
s -> do (a
a,[i] -> [i]
s') <- LazyBuilderT i m a -> ([i] -> [i]) -> m (a, [i] -> [i])
forall i (m :: * -> *) a.
LazyBuilderT i m a -> ([i] -> [i]) -> m (a, [i] -> [i])
runLazyBuilderT LazyBuilderT i m a
m [i] -> [i]
s; LazyBuilderT i m b -> ([i] -> [i]) -> m (b, [i] -> [i])
forall i (m :: * -> *) a.
LazyBuilderT i m a -> ([i] -> [i]) -> m (a, [i] -> [i])
runLazyBuilderT (a -> LazyBuilderT i m b
f a
a) [i] -> [i]
s'
instance MonadTrans (LazyBuilderT i) where
lift :: m a -> LazyBuilderT i m a
lift m a
m = (([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
forall i (m :: * -> *) a.
(([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
LazyBuilder ((([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a)
-> (([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
forall a b. (a -> b) -> a -> b
$ \[i] -> [i]
s -> do a
a <- m a
m; (a, [i] -> [i]) -> m (a, [i] -> [i])
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,[i] -> [i]
s)
instance ListBuilder (LazyBuilder i) i where
li :: i -> LazyBuilder i ()
li i
a = (([i] -> [i]) -> Identity ((), [i] -> [i])) -> LazyBuilder i ()
forall i (m :: * -> *) a.
(([i] -> [i]) -> m (a, [i] -> [i])) -> LazyBuilderT i m a
LazyBuilder ((([i] -> [i]) -> Identity ((), [i] -> [i])) -> LazyBuilder i ())
-> (([i] -> [i]) -> Identity ((), [i] -> [i])) -> LazyBuilder i ()
forall a b. (a -> b) -> a -> b
$ \[i] -> [i]
s -> ((), [i] -> [i]) -> Identity ((), [i] -> [i])
forall (m :: * -> *) a. Monad m => a -> m a
return ((),[i] -> [i]
s([i] -> [i]) -> ([i] -> [i]) -> [i] -> [i]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([i
a][i] -> [i] -> [i]
forall a. [a] -> [a] -> [a]
++))
buildList :: LazyBuilder i () -> [i]
buildList LazyBuilder i ()
m = (([i] -> [i]) -> [i] -> [i]
forall a b. (a -> b) -> a -> b
$[]) (([i] -> [i]) -> [i]) -> ([i] -> [i]) -> [i]
forall a b. (a -> b) -> a -> b
$ ((), [i] -> [i]) -> [i] -> [i]
forall a b. (a, b) -> b
snd (((), [i] -> [i]) -> [i] -> [i]) -> ((), [i] -> [i]) -> [i] -> [i]
forall a b. (a -> b) -> a -> b
$ Identity ((), [i] -> [i]) -> ((), [i] -> [i])
forall a. Identity a -> a
runIdentity (Identity ((), [i] -> [i]) -> ((), [i] -> [i]))
-> Identity ((), [i] -> [i]) -> ((), [i] -> [i])
forall a b. (a -> b) -> a -> b
$ LazyBuilder i () -> ([i] -> [i]) -> Identity ((), [i] -> [i])
forall i (m :: * -> *) a.
LazyBuilderT i m a -> ([i] -> [i]) -> m (a, [i] -> [i])
runLazyBuilderT LazyBuilder i ()
m ([][i] -> [i] -> [i]
forall a. [a] -> [a] -> [a]
++)
lazyBuild :: LazyBuilderT i Identity () -> [i]
lazyBuild :: LazyBuilderT i Identity () -> [i]
lazyBuild = LazyBuilderT i Identity () -> [i]
forall (l :: * -> *) i. ListBuilder l i => l () -> [i]
buildList
lis :: ListBuilder l i => [i] -> l ()
lis :: [i] -> l ()
lis = (i -> l ()) -> [i] -> l ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ i -> l ()
forall (l :: * -> *) i. ListBuilder l i => i -> l ()
li
lit :: ListBuilder l (a,b) => a -> b -> l ()
lit :: a -> b -> l ()
lit a
a b
b = (a, b) -> l ()
forall (l :: * -> *) i. ListBuilder l i => i -> l ()
li (a
a,b
b)
(>-<) :: ListBuilder l (a,b) => a -> b -> l ()
>-< :: a -> b -> l ()
(>-<) = a -> b -> l ()
forall (l :: * -> *) a b. ListBuilder l (a, b) => a -> b -> l ()
lit