{-# LANGUAGE TypeOperators, FlexibleContexts, FlexibleInstances, MultiParamTypeClasses, UndecidableInstances, Rank2Types #-}
module Control.Ev.Util
(
Reader(Reader,ask)
, reader
, State(State,get,put)
, state
, Writer(Writer,tell)
, writer
, Except(Except,throwError)
, catchError, exceptEither, exceptMaybe, exceptDefault
, Choose(Choose,none,choose)
, chooseFirst, chooseAll
) where
import Control.Ev.Eff
import Control.Monad
import Control.Applicative
data Reader a e ans = Reader { Reader a e ans -> Op () a e ans
ask :: !(Op () a e ans)
}
{-# INLINE reader #-}
reader :: a -> Eff (Reader a :* e) ans -> Eff e ans
reader :: a -> Eff (Reader a :* e) ans -> Eff e ans
reader a
x
= Reader a e ans -> Eff (Reader a :* e) ans -> Eff e ans
forall (h :: * -> * -> *) e ans.
h e ans -> Eff (h :* e) ans -> Eff e ans
handler (Reader :: forall a e ans. Op () a e ans -> Reader a e ans
Reader{ ask :: Op () a e ans
ask = a -> Op () a e ans
forall a e ans. a -> Op () a e ans
value a
x })
data State a e ans = State { State a e ans -> Op () a e ans
get :: !(Op () a e ans)
, State a e ans -> Op a () e ans
put :: !(Op a () e ans)
}
{-# INLINE state #-}
state :: a -> Eff (State a :* e) ans -> Eff e ans
state :: a -> Eff (State a :* e) ans -> Eff e ans
state a
init
= a
-> State a (Local a :* e) ans
-> Eff (State a :* e) ans
-> Eff e ans
forall a (h :: * -> * -> *) e ans.
a -> h (Local a :* e) ans -> Eff (h :* e) ans -> Eff e ans
handlerLocal a
init (State :: forall a e ans. Op () a e ans -> Op a () e ans -> State a e ans
State{ get :: Op () a (Local a :* e) ans
get = (() -> Eff (Local a :* e) a) -> Op () a (Local a :* e) ans
forall a e b ans. (a -> Eff e b) -> Op a b e ans
function (\()
_ -> Eff (Local a :* e) a
forall a e. Eff (Local a :* e) a
localGet),
put :: Op a () (Local a :* e) ans
put = (a -> Eff (Local a :* e) ()) -> Op a () (Local a :* e) ans
forall a e b ans. (a -> Eff e b) -> Op a b e ans
function (\a
x -> a -> Eff (Local a :* e) ()
forall a e. a -> Eff (Local a :* e) ()
localPut a
x) })
data Writer a e ans = Writer { Writer a e ans -> Op a () e ans
tell :: !(Op a () e ans)
}
{-# INLINE writer #-}
writer :: (Monoid a) => Eff (Writer a :* e) ans -> Eff e (ans,a)
writer :: Eff (Writer a :* e) ans -> Eff e (ans, a)
writer
= a
-> (ans -> a -> (ans, a))
-> Writer a (Local a :* e) (ans, a)
-> Eff (Writer a :* e) ans
-> Eff e (ans, a)
forall a ans b (h :: * -> * -> *) e.
a
-> (ans -> a -> b)
-> h (Local a :* e) b
-> Eff (h :* e) ans
-> Eff e b
handlerLocalRet a
forall a. Monoid a => a
mempty (,) (Writer a (Local a :* e) (ans, a)
-> Eff (Writer a :* e) ans -> Eff e (ans, a))
-> Writer a (Local a :* e) (ans, a)
-> Eff (Writer a :* e) ans
-> Eff e (ans, a)
forall a b. (a -> b) -> a -> b
$
Writer :: forall a e ans. Op a () e ans -> Writer a e ans
Writer{ tell :: Op a () (Local a :* e) (ans, a)
tell = (a -> Eff (Local a :* e) ()) -> Op a () (Local a :* e) (ans, a)
forall a e b ans. (a -> Eff e b) -> Op a b e ans
function (\a
x -> do{ a
xs <- Eff (Local a :* e) a
forall a e. Eff (Local a :* e) a
localGet; a -> Eff (Local a :* e) ()
forall a e. a -> Eff (Local a :* e) ()
localPut (a -> a -> a
forall a. Monoid a => a -> a -> a
mappend a
xs a
x); () -> Eff (Local a :* e) ()
forall (m :: * -> *) a. Monad m => a -> m a
return () }) }
data Except a e ans = Except { Except a e ans -> forall b. Op a b e ans
throwError :: !(forall b. Op a b e ans)
}
catchError :: Eff (Except a :* e) ans -> (a -> Eff e ans) -> Eff e ans
catchError :: Eff (Except a :* e) ans -> (a -> Eff e ans) -> Eff e ans
catchError Eff (Except a :* e) ans
action a -> Eff e ans
h
= Except a e ans -> Eff (Except a :* e) ans -> Eff e ans
forall (h :: * -> * -> *) e ans.
h e ans -> Eff (h :* e) ans -> Eff e ans
handler (Except :: forall a e ans. (forall b. Op a b e ans) -> Except a e ans
Except{ throwError :: forall b. Op a b e ans
throwError = (a -> Eff e ans) -> Op a b e ans
forall a e ans b. (a -> Eff e ans) -> Op a b e ans
except (\a
x -> a -> Eff e ans
h a
x) }) Eff (Except a :* e) ans
action
exceptEither :: Eff (Except a :* e) ans -> Eff e (Either a ans)
exceptEither :: Eff (Except a :* e) ans -> Eff e (Either a ans)
exceptEither
= (ans -> Either a ans)
-> Except a e (Either a ans)
-> Eff (Except a :* e) ans
-> Eff e (Either a ans)
forall ans a (h :: * -> * -> *) e.
(ans -> a) -> h e a -> Eff (h :* e) ans -> Eff e a
handlerRet ans -> Either a ans
forall a b. b -> Either a b
Right (Except :: forall a e ans. (forall b. Op a b e ans) -> Except a e ans
Except{ throwError :: forall b. Op a b e (Either a ans)
throwError = (a -> Eff e (Either a ans)) -> Op a b e (Either a ans)
forall a e ans b. (a -> Eff e ans) -> Op a b e ans
except (\a
x -> Either a ans -> Eff e (Either a ans)
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> Either a ans
forall a b. a -> Either a b
Left a
x) ) })
exceptDefault :: ans -> Eff (Except a :* e) ans -> Eff e ans
exceptDefault :: ans -> Eff (Except a :* e) ans -> Eff e ans
exceptDefault ans
def
= Except a e ans -> Eff (Except a :* e) ans -> Eff e ans
forall (h :: * -> * -> *) e ans.
h e ans -> Eff (h :* e) ans -> Eff e ans
handler (Except :: forall a e ans. (forall b. Op a b e ans) -> Except a e ans
Except{ throwError :: forall b. Op a b e ans
throwError = (a -> Eff e ans) -> Op a b e ans
forall a e ans b. (a -> Eff e ans) -> Op a b e ans
except (\a
_ -> ans -> Eff e ans
forall (m :: * -> *) a. Monad m => a -> m a
return ans
def) })
exceptMaybe :: Eff (Except a :* e) ans -> Eff e (Maybe ans)
exceptMaybe :: Eff (Except a :* e) ans -> Eff e (Maybe ans)
exceptMaybe
= (ans -> Maybe ans)
-> Except a e (Maybe ans)
-> Eff (Except a :* e) ans
-> Eff e (Maybe ans)
forall ans a (h :: * -> * -> *) e.
(ans -> a) -> h e a -> Eff (h :* e) ans -> Eff e a
handlerRet ans -> Maybe ans
forall a. a -> Maybe a
Just (Except :: forall a e ans. (forall b. Op a b e ans) -> Except a e ans
Except{ throwError :: forall b. Op a b e (Maybe ans)
throwError = (a -> Eff e (Maybe ans)) -> Op a b e (Maybe ans)
forall a e ans b. (a -> Eff e ans) -> Op a b e ans
except (\a
_ -> Maybe ans -> Eff e (Maybe ans)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ans
forall a. Maybe a
Nothing) })
data Choose e ans = Choose { Choose e ans -> forall a. Op () a e ans
none :: !(forall a. Op () a e ans)
, Choose e ans -> Op Int Int e ans
choose :: !(Op Int Int e ans)
}
chooseFirst :: Eff (Choose :* e) ans -> Eff e (Maybe ans)
chooseFirst :: Eff (Choose :* e) ans -> Eff e (Maybe ans)
chooseFirst
= (ans -> Maybe ans)
-> Choose e (Maybe ans)
-> Eff (Choose :* e) ans
-> Eff e (Maybe ans)
forall ans a (h :: * -> * -> *) e.
(ans -> a) -> h e a -> Eff (h :* e) ans -> Eff e a
handlerRet ans -> Maybe ans
forall a. a -> Maybe a
Just (Choose e (Maybe ans)
-> Eff (Choose :* e) ans -> Eff e (Maybe ans))
-> Choose e (Maybe ans)
-> Eff (Choose :* e) ans
-> Eff e (Maybe ans)
forall a b. (a -> b) -> a -> b
$
Choose :: forall e ans.
(forall a. Op () a e ans) -> Op Int Int e ans -> Choose e ans
Choose{ none :: forall a. Op () a e (Maybe ans)
none = (() -> Eff e (Maybe ans)) -> Op () a e (Maybe ans)
forall a e ans b. (a -> Eff e ans) -> Op a b e ans
except (\()
_ -> Maybe ans -> Eff e (Maybe ans)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ans
forall a. Maybe a
Nothing)
, choose :: Op Int Int e (Maybe ans)
choose = (Int -> (Int -> Eff e (Maybe ans)) -> Eff e (Maybe ans))
-> Op Int Int e (Maybe ans)
forall a b e ans.
(a -> (b -> Eff e ans) -> Eff e ans) -> Op a b e ans
operation (\Int
hi Int -> Eff e (Maybe ans)
k -> let try :: Int -> Eff e (Maybe ans)
try Int
n = if (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
hi)
then Maybe ans -> Eff e (Maybe ans)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ans
forall a. Maybe a
Nothing
else do Maybe ans
x <- Int -> Eff e (Maybe ans)
k Int
n
case Maybe ans
x of
Maybe ans
Nothing -> Int -> Eff e (Maybe ans)
try (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
Maybe ans
_ -> Maybe ans -> Eff e (Maybe ans)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ans
x
in Int -> Eff e (Maybe ans)
try Int
1)
}
chooseAll :: Eff (Choose :* e) a -> Eff e [a]
chooseAll :: Eff (Choose :* e) a -> Eff e [a]
chooseAll
= (a -> [a]) -> Choose e [a] -> Eff (Choose :* e) a -> Eff e [a]
forall ans a (h :: * -> * -> *) e.
(ans -> a) -> h e a -> Eff (h :* e) ans -> Eff e a
handlerRet (\a
x -> [a
x]) (Choose e [a] -> Eff (Choose :* e) a -> Eff e [a])
-> Choose e [a] -> Eff (Choose :* e) a -> Eff e [a]
forall a b. (a -> b) -> a -> b
$
Choose :: forall e ans.
(forall a. Op () a e ans) -> Op Int Int e ans -> Choose e ans
Choose{ none :: forall a. Op () a e [a]
none = (() -> Eff e [a]) -> Op () a e [a]
forall a e ans b. (a -> Eff e ans) -> Op a b e ans
except (\()
_ -> [a] -> Eff e [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [])
, choose :: Op Int Int e [a]
choose = (Int -> (Int -> Eff e [a]) -> Eff e [a]) -> Op Int Int e [a]
forall a b e ans.
(a -> (b -> Eff e ans) -> Eff e ans) -> Op a b e ans
operation (\Int
hi Int -> Eff e [a]
k -> let collect :: Int -> [a] -> Eff e [a]
collect Int
0 [a]
acc = [a] -> Eff e [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [a]
acc
collect Int
n [a]
acc = do [a]
xs <- Int -> Eff e [a]
k Int
n
Int -> [a] -> Eff e [a]
collect (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) ([a] -> Eff e [a]) -> [a] -> Eff e [a]
forall a b. (a -> b) -> a -> b
$! ([a]
xs [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
acc)
in Int -> [a] -> Eff e [a]
collect Int
hi [])
}
instance (Choose :? e) => Alternative (Eff e) where
empty :: Eff e a
empty = (forall e' ans. Choose e' ans -> Op () a e' ans) -> () -> Eff e a
forall (h :: * -> * -> *) e a b.
(h :? e) =>
(forall e' ans. h e' ans -> Op a b e' ans) -> a -> Eff e b
perform forall e' ans. Choose e' ans -> Op () a e' ans
forall e ans. Choose e ans -> forall a. Op () a e ans
none ()
Eff e a
m1 <|> :: Eff e a -> Eff e a -> Eff e a
<|> Eff e a
m2 = do Int
x <- (forall e' ans. Choose e' ans -> Op Int Int e' ans)
-> Int -> Eff e Int
forall (h :: * -> * -> *) e a b.
(h :? e) =>
(forall e' ans. h e' ans -> Op a b e' ans) -> a -> Eff e b
perform forall e' ans. Choose e' ans -> Op Int Int e' ans
choose Int
2
if (Int
xInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
1) then Eff e a
m1 else Eff e a
m2
instance (Choose :? e) => MonadPlus (Eff e) where
mzero :: Eff e a
mzero = (forall e' ans. Choose e' ans -> Op () a e' ans) -> () -> Eff e a
forall (h :: * -> * -> *) e a b.
(h :? e) =>
(forall e' ans. h e' ans -> Op a b e' ans) -> a -> Eff e b
perform forall e' ans. Choose e' ans -> Op () a e' ans
forall e ans. Choose e ans -> forall a. Op () a e ans
none ()
mplus :: Eff e a -> Eff e a -> Eff e a
mplus Eff e a
m1 Eff e a
m2 = do Int
x <- (forall e' ans. Choose e' ans -> Op Int Int e' ans)
-> Int -> Eff e Int
forall (h :: * -> * -> *) e a b.
(h :? e) =>
(forall e' ans. h e' ans -> Op a b e' ans) -> a -> Eff e b
perform forall e' ans. Choose e' ans -> Op Int Int e' ans
choose Int
2
if (Int
xInt -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
1) then Eff e a
m1 else Eff e a
m2