{-# LANGUAGE RankNTypes #-}
module HaskellCI.List (
    ListBuilder,
    buildList,
    item,
    ) where

import HaskellCI.Prelude

newtype ListBuilder x a = LB { forall x a.
ListBuilder x a -> forall r. (([x] -> [x]) -> a -> r) -> r
unLB :: forall r. (([x] -> [x]) -> a -> r) -> r }

instance Functor (ListBuilder x) where
    fmap :: forall a b. (a -> b) -> ListBuilder x a -> ListBuilder x b
fmap a -> b
f (LB forall r. (([x] -> [x]) -> a -> r) -> r
k) = forall x a.
(forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
LB forall a b. (a -> b) -> a -> b
$ forall r. (([x] -> [x]) -> a -> r) -> r
k forall a b. (a -> b) -> a -> b
$ \[x] -> [x]
endo a
a ([x] -> [x]) -> b -> r
k' -> ([x] -> [x]) -> b -> r
k' [x] -> [x]
endo (a -> b
f a
a)

instance Applicative (ListBuilder x) where
    pure :: forall a. a -> ListBuilder x a
pure a
x = forall x a.
(forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
LB forall a b. (a -> b) -> a -> b
$ \([x] -> [x]) -> a -> r
f -> ([x] -> [x]) -> a -> r
f forall a. a -> a
id a
x
    <*> :: forall a b.
ListBuilder x (a -> b) -> ListBuilder x a -> ListBuilder x b
(<*>)  = forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap

instance Monad (ListBuilder x) where
    return :: forall a. a -> ListBuilder x a
return = forall (f :: * -> *) a. Applicative f => a -> f a
pure

    ListBuilder x a
m >>= :: forall a b.
ListBuilder x a -> (a -> ListBuilder x b) -> ListBuilder x b
>>= a -> ListBuilder x b
k =
        forall x a.
(forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
LB forall a b. (a -> b) -> a -> b
$ \([x] -> [x]) -> b -> r
r ->
        forall x a.
ListBuilder x a -> forall r. (([x] -> [x]) -> a -> r) -> r
unLB ListBuilder x a
m forall a b. (a -> b) -> a -> b
$ \[x] -> [x]
endo1 a
a ->
        forall x a.
ListBuilder x a -> forall r. (([x] -> [x]) -> a -> r) -> r
unLB (a -> ListBuilder x b
k a
a) forall a b. (a -> b) -> a -> b
$ \[x] -> [x]
endo2 b
b ->
        ([x] -> [x]) -> b -> r
r ([x] -> [x]
endo1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. [x] -> [x]
endo2) b
b

buildList :: ListBuilder x () -> [x]
buildList :: forall x. ListBuilder x () -> [x]
buildList (LB forall r. (([x] -> [x]) -> () -> r) -> r
f) = forall r. (([x] -> [x]) -> () -> r) -> r
f forall a b. (a -> b) -> a -> b
$ \[x] -> [x]
endo ()
_ -> [x] -> [x]
endo []

item :: x -> ListBuilder x ()
item :: forall x. x -> ListBuilder x ()
item x
x = forall x a.
(forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
LB forall a b. (a -> b) -> a -> b
$ \([x] -> [x]) -> () -> r
f -> ([x] -> [x]) -> () -> r
f (x
x forall a. a -> [a] -> [a]
:) ()