{-# 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 r. (([x] -> [x]) -> b -> r) -> r) -> ListBuilder x b
forall x a.
(forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
LB ((forall r. (([x] -> [x]) -> b -> r) -> r) -> ListBuilder x b)
-> (forall r. (([x] -> [x]) -> b -> r) -> r) -> ListBuilder x b
forall a b. (a -> b) -> a -> b
$ (([x] -> [x]) -> a -> (([x] -> [x]) -> b -> r) -> r)
-> (([x] -> [x]) -> b -> r) -> r
forall r. (([x] -> [x]) -> a -> r) -> r
k ((([x] -> [x]) -> a -> (([x] -> [x]) -> b -> r) -> r)
 -> (([x] -> [x]) -> b -> r) -> r)
-> (([x] -> [x]) -> a -> (([x] -> [x]) -> b -> r) -> r)
-> (([x] -> [x]) -> b -> r)
-> r
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 r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
forall x a.
(forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
LB ((forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a)
-> (forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
forall a b. (a -> b) -> a -> b
$ \([x] -> [x]) -> a -> r
f -> ([x] -> [x]) -> a -> r
f [x] -> [x]
forall a. a -> a
id a
x
    <*> :: forall a b.
ListBuilder x (a -> b) -> ListBuilder x a -> ListBuilder x 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 = a -> ListBuilder x a
forall a. a -> ListBuilder x a
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 r. (([x] -> [x]) -> b -> r) -> r) -> ListBuilder x b
forall x a.
(forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
LB ((forall r. (([x] -> [x]) -> b -> r) -> r) -> ListBuilder x b)
-> (forall r. (([x] -> [x]) -> b -> r) -> r) -> ListBuilder x b
forall a b. (a -> b) -> a -> b
$ \([x] -> [x]) -> b -> r
r ->
        ListBuilder x a -> forall r. (([x] -> [x]) -> a -> r) -> r
forall x a.
ListBuilder x a -> forall r. (([x] -> [x]) -> a -> r) -> r
unLB ListBuilder x a
m ((([x] -> [x]) -> a -> r) -> r) -> (([x] -> [x]) -> a -> r) -> r
forall a b. (a -> b) -> a -> b
$ \[x] -> [x]
endo1 a
a ->
        ListBuilder x b -> forall r. (([x] -> [x]) -> b -> r) -> r
forall x a.
ListBuilder x a -> forall r. (([x] -> [x]) -> a -> r) -> r
unLB (a -> ListBuilder x b
k a
a) ((([x] -> [x]) -> b -> r) -> r) -> (([x] -> [x]) -> b -> r) -> r
forall a b. (a -> b) -> a -> b
$ \[x] -> [x]
endo2 b
b ->
        ([x] -> [x]) -> b -> r
r ([x] -> [x]
endo1 ([x] -> [x]) -> ([x] -> [x]) -> [x] -> [x]
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) = (([x] -> [x]) -> () -> [x]) -> [x]
forall r. (([x] -> [x]) -> () -> r) -> r
f ((([x] -> [x]) -> () -> [x]) -> [x])
-> (([x] -> [x]) -> () -> [x]) -> [x]
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 r. (([x] -> [x]) -> () -> r) -> r) -> ListBuilder x ()
forall x a.
(forall r. (([x] -> [x]) -> a -> r) -> r) -> ListBuilder x a
LB ((forall r. (([x] -> [x]) -> () -> r) -> r) -> ListBuilder x ())
-> (forall r. (([x] -> [x]) -> () -> r) -> r) -> ListBuilder x ()
forall a b. (a -> b) -> a -> b
$ \([x] -> [x]) -> () -> r
f -> ([x] -> [x]) -> () -> r
f (x
x x -> [x] -> [x]
forall a. a -> [a] -> [a]
:) ()