{-# LANGUAGE NoMonoLocalBinds #-}
{-# LANGUAGE NoMonomorphismRestriction #-}

module Bluefin.Internal.Examples where

import Bluefin.Internal hiding (w)
import Control.Exception (IOException)
import qualified Control.Exception
import Control.Monad (forever, unless, when)
import Control.Monad.IO.Class (liftIO)
import Data.Foldable (for_)
import Data.Monoid (Any (Any, getAny))
import Text.Read (readMaybe)
import Prelude hiding
  ( break,
    drop,
    head,
    read,
    readFile,
    return,
    writeFile,
  )
import qualified Prelude

monadIOExample :: IO ()
monadIOExample :: IO ()
monadIOExample = (forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) ())
-> IO ()
forall a.
(forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a)
-> IO a
runEff ((forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) ())
 -> IO ())
-> (forall (e :: Effects) (es :: Effects).
    IOE e -> Eff (e :& es) ())
-> IO ()
forall a b. (a -> b) -> a -> b
$ \IOE e
io -> IOE e
-> (forall {m :: * -> *}. MonadIO m => m ()) -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
IOE e -> (forall (m :: * -> *). MonadIO m => m r) -> Eff es r
withMonadIO IOE e
io ((forall {m :: * -> *}. MonadIO m => m ()) -> Eff (e :& es) ())
-> (forall {m :: * -> *}. MonadIO m => m ()) -> Eff (e :& es) ()
forall a b. (a -> b) -> a -> b
$ IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
  [Char]
name <- IO [Char]
forall a. Read a => IO a
readLn
  [Char] -> IO ()
putStrLn ([Char]
"Hello " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
name)

monadFailExample :: Either String ()
monadFailExample :: Either [Char] ()
monadFailExample = (forall (es :: Effects). Eff es (Either [Char] ()))
-> Either [Char] ()
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es (Either [Char] ()))
 -> Either [Char] ())
-> (forall (es :: Effects). Eff es (Either [Char] ()))
-> Either [Char] ()
forall a b. (a -> b) -> a -> b
$ (forall (ex :: Effects). Exception [Char] ex -> Eff (ex :& es) ())
-> Eff es (Either [Char] ())
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects). Exception [Char] ex -> Eff (ex :& es) ())
 -> Eff es (Either [Char] ()))
-> (forall (ex :: Effects).
    Exception [Char] ex -> Eff (ex :& es) ())
-> Eff es (Either [Char] ())
forall a b. (a -> b) -> a -> b
$ \Exception [Char] ex
e ->
  Bool -> Eff (ex :& es) () -> Eff (ex :& es) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ((Int
2 :: Int) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1) (Eff (ex :& es) () -> Eff (ex :& es) ())
-> Eff (ex :& es) () -> Eff (ex :& es) ()
forall a b. (a -> b) -> a -> b
$
    Exception [Char] ex
-> (forall (m :: * -> *). MonadFail m => m ()) -> Eff (ex :& es) ()
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Exception [Char] e
-> (forall (m :: * -> *). MonadFail m => m r) -> Eff es r
withMonadFail Exception [Char] ex
e ([Char] -> m ()
forall a. [Char] -> m a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail [Char]
"2 was bigger than 1")

throwExample :: Either Int String
throwExample :: Either Int [Char]
throwExample = (forall (es :: Effects). Eff es (Either Int [Char]))
-> Either Int [Char]
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es (Either Int [Char]))
 -> Either Int [Char])
-> (forall (es :: Effects). Eff es (Either Int [Char]))
-> Either Int [Char]
forall a b. (a -> b) -> a -> b
$ (forall (ex :: Effects). Exception Int ex -> Eff (ex :& es) [Char])
-> Eff es (Either Int [Char])
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception Int ex -> Eff (ex :& es) [Char])
 -> Eff es (Either Int [Char]))
-> (forall (ex :: Effects).
    Exception Int ex -> Eff (ex :& es) [Char])
-> Eff es (Either Int [Char])
forall a b. (a -> b) -> a -> b
$ \Exception Int ex
e -> do
  Any
_ <- Exception Int ex -> Int -> Eff (ex :& es) Any
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception Int ex
e Int
42
  [Char] -> Eff (ex :& es) [Char]
forall a. a -> Eff (ex :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"No exception thrown"

handleExample :: String
handleExample :: [Char]
handleExample = (forall (es :: Effects). Eff es [Char]) -> [Char]
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es [Char]) -> [Char])
-> (forall (es :: Effects). Eff es [Char]) -> [Char]
forall a b. (a -> b) -> a -> b
$ (Int -> Eff es [Char])
-> (forall {ex :: Effects}.
    Exception Int ex -> Eff (ex :& es) [Char])
-> Eff es [Char]
forall e (es :: Effects) a.
(e -> Eff es a)
-> (forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es a
handle ([Char] -> Eff es [Char]
forall a. a -> Eff es a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char] -> Eff es [Char])
-> (Int -> [Char]) -> Int -> Eff es [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Char]
forall a. Show a => a -> [Char]
show) ((forall {ex :: Effects}.
  Exception Int ex -> Eff (ex :& es) [Char])
 -> Eff es [Char])
-> (forall {ex :: Effects}.
    Exception Int ex -> Eff (ex :& es) [Char])
-> Eff es [Char]
forall a b. (a -> b) -> a -> b
$ \Exception Int ex
e -> do
  Any
_ <- Exception Int ex -> Int -> Eff (ex :& es) Any
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception Int ex
e (Int
42 :: Int)
  [Char] -> Eff (ex :& es) [Char]
forall a. a -> Eff (ex :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"No exception thrown"

exampleGet :: (Int, Int)
exampleGet :: (Int, Int)
exampleGet = (forall (es :: Effects). Eff es (Int, Int)) -> (Int, Int)
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es (Int, Int)) -> (Int, Int))
-> (forall (es :: Effects). Eff es (Int, Int)) -> (Int, Int)
forall a b. (a -> b) -> a -> b
$ Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es (Int, Int)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState Int
10 ((forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
 -> Eff es (Int, Int))
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es (Int, Int)
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
  Int
n <- State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st
  Int -> Eff (st :& es) Int
forall a. a -> Eff (st :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n)

examplePut :: ((), Int)
examplePut :: ((), Int)
examplePut = (forall (es :: Effects). Eff es ((), Int)) -> ((), Int)
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ((), Int)) -> ((), Int))
-> (forall (es :: Effects). Eff es ((), Int)) -> ((), Int)
forall a b. (a -> b) -> a -> b
$ Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) ())
-> Eff es ((), Int)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState Int
10 ((forall {st :: Effects}. State Int st -> Eff (st :& es) ())
 -> Eff es ((), Int))
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) ())
-> Eff es ((), Int)
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
  State Int st -> Int -> Eff (st :& es) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int st
st Int
30

exampleModify :: ((), Int)
exampleModify :: ((), Int)
exampleModify = (forall (es :: Effects). Eff es ((), Int)) -> ((), Int)
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ((), Int)) -> ((), Int))
-> (forall (es :: Effects). Eff es ((), Int)) -> ((), Int)
forall a b. (a -> b) -> a -> b
$ Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) ())
-> Eff es ((), Int)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState Int
10 ((forall {st :: Effects}. State Int st -> Eff (st :& es) ())
 -> Eff es ((), Int))
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) ())
-> Eff es ((), Int)
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
  State Int st -> (Int -> Int) -> Eff (st :& es) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int st
st (Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
2)

yieldExample :: ([Int], ())
yieldExample :: ([Int], ())
yieldExample = (forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ())
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ()))
-> (forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ())
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
-> Eff es ([Int], ())
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList ((forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
 -> Eff es ([Int], ()))
-> (forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
-> Eff es ([Int], ())
forall a b. (a -> b) -> a -> b
$ \Stream Int e1
y -> do
  Stream Int e1 -> Int -> Eff (e1 :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream Int e1
y Int
1
  Stream Int e1 -> Int -> Eff (e1 :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream Int e1
y Int
2
  Stream Int e1 -> Int -> Eff (e1 :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream Int e1
y Int
100

withYieldToListExample :: Int
withYieldToListExample :: Int
withYieldToListExample = (forall (es :: Effects). Eff es Int) -> Int
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es Int) -> Int)
-> (forall (es :: Effects). Eff es Int) -> Int
forall a b. (a -> b) -> a -> b
$ (forall (e :: Effects).
 Stream Integer e -> Eff (e :& es) ([Integer] -> Int))
-> Eff es Int
forall a (es :: Effects) r.
(forall (e :: Effects). Stream a e -> Eff (e :& es) ([a] -> r))
-> Eff es r
withYieldToList ((forall (e :: Effects).
  Stream Integer e -> Eff (e :& es) ([Integer] -> Int))
 -> Eff es Int)
-> (forall (e :: Effects).
    Stream Integer e -> Eff (e :& es) ([Integer] -> Int))
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \Stream Integer e
y -> do
  Stream Integer e -> Integer -> Eff (e :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream Integer e
y Integer
1
  Stream Integer e -> Integer -> Eff (e :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream Integer e
y Integer
2
  Stream Integer e -> Integer -> Eff (e :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream Integer e
y Integer
100
  ([Integer] -> Int) -> Eff (e :& es) ([Integer] -> Int)
forall a. a -> Eff (e :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Integer] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length

forEachExample :: ([Int], ())
forEachExample :: ([Int], ())
forEachExample = (forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ())
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ()))
-> (forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ())
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
-> Eff es ([Int], ())
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList ((forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
 -> Eff es ([Int], ()))
-> (forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
-> Eff es ([Int], ())
forall a b. (a -> b) -> a -> b
$ \Stream Int e1
y -> do
  (forall (e1 :: Effects).
 Coroutine Int () e1 -> Eff (e1 :& (e1 :& es)) ())
-> (Int -> Eff (e1 :& es) ()) -> Eff (e1 :& es) ()
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach ([Int] -> Coroutine Int () e1 -> Eff (e1 :& (e1 :& es)) ()
forall (t :: * -> *) (e1 :: Effects) (es :: Effects) a.
(Foldable t, e1 :> es) =>
t a -> Stream a e1 -> Eff es ()
inFoldable [Int
0 .. Int
4]) ((Int -> Eff (e1 :& es) ()) -> Eff (e1 :& es) ())
-> (Int -> Eff (e1 :& es) ()) -> Eff (e1 :& es) ()
forall a b. (a -> b) -> a -> b
$ \Int
i -> do
    Stream Int e1 -> Int -> Eff (e1 :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream Int e1
y Int
i
    Stream Int e1 -> Int -> Eff (e1 :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream Int e1
y (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
10)

inFoldableExample :: ([Int], ())
inFoldableExample :: ([Int], ())
inFoldableExample = (forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ())
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ()))
-> (forall (es :: Effects). Eff es ([Int], ())) -> ([Int], ())
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
-> Eff es ([Int], ())
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList ((forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
 -> Eff es ([Int], ()))
-> (forall (e1 :: Effects). Stream Int e1 -> Eff (e1 :& es) ())
-> Eff es ([Int], ())
forall a b. (a -> b) -> a -> b
$ [Int] -> Stream Int e1 -> Eff (e1 :& es) ()
forall (t :: * -> *) (e1 :: Effects) (es :: Effects) a.
(Foldable t, e1 :> es) =>
t a -> Stream a e1 -> Eff es ()
inFoldable [Int
1, Int
2, Int
100]

enumerateExample :: ([(Int, String)], ())
enumerateExample :: ([(Int, [Char])], ())
enumerateExample = (forall (es :: Effects). Eff es ([(Int, [Char])], ()))
-> ([(Int, [Char])], ())
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ([(Int, [Char])], ()))
 -> ([(Int, [Char])], ()))
-> (forall (es :: Effects). Eff es ([(Int, [Char])], ()))
-> ([(Int, [Char])], ())
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects).
 Stream (Int, [Char]) e1 -> Eff (e1 :& es) ())
-> Eff es ([(Int, [Char])], ())
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList ((forall (e1 :: Effects).
  Stream (Int, [Char]) e1 -> Eff (e1 :& es) ())
 -> Eff es ([(Int, [Char])], ()))
-> (forall (e1 :: Effects).
    Stream (Int, [Char]) e1 -> Eff (e1 :& es) ())
-> Eff es ([(Int, [Char])], ())
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects).
 Stream [Char] e1 -> Eff (e1 :& (e1 :& es)) ())
-> Stream (Int, [Char]) e1 -> Eff (e1 :& es) ()
forall (e2 :: Effects) (es :: Effects) a r.
(e2 :> es) =>
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream (Int, a) e2 -> Eff es r
enumerate ([[Char]] -> Stream [Char] e1 -> Eff (e1 :& (e1 :& es)) ()
forall (t :: * -> *) (e1 :: Effects) (es :: Effects) a.
(Foldable t, e1 :> es) =>
t a -> Stream a e1 -> Eff es ()
inFoldable [[Char]
"A", [Char]
"B", [Char]
"C"])

returnEarlyExample :: String
returnEarlyExample :: [Char]
returnEarlyExample = (forall (es :: Effects). Eff es [Char]) -> [Char]
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es [Char]) -> [Char])
-> (forall (es :: Effects). Eff es [Char]) -> [Char]
forall a b. (a -> b) -> a -> b
$ (forall (er :: Effects).
 EarlyReturn [Char] er -> Eff (er :& es) [Char])
-> Eff es [Char]
forall r (es :: Effects).
(forall (er :: Effects). EarlyReturn r er -> Eff (er :& es) r)
-> Eff es r
withEarlyReturn ((forall (er :: Effects).
  EarlyReturn [Char] er -> Eff (er :& es) [Char])
 -> Eff es [Char])
-> (forall (er :: Effects).
    EarlyReturn [Char] er -> Eff (er :& es) [Char])
-> Eff es [Char]
forall a b. (a -> b) -> a -> b
$ \EarlyReturn [Char] er
e -> do
  [Int] -> (Int -> Eff (er :& es) ()) -> Eff (er :& es) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Int
1 :: Int .. Int
10] ((Int -> Eff (er :& es) ()) -> Eff (er :& es) ())
-> (Int -> Eff (er :& es) ()) -> Eff (er :& es) ()
forall a b. (a -> b) -> a -> b
$ \Int
i -> do
    Bool -> Eff (er :& es) () -> Eff (er :& es) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
5) (Eff (er :& es) () -> Eff (er :& es) ())
-> Eff (er :& es) () -> Eff (er :& es) ()
forall a b. (a -> b) -> a -> b
$
      EarlyReturn [Char] er -> [Char] -> Eff (er :& es) ()
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
returnEarly EarlyReturn [Char] er
e ([Char]
"Returned early with " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i)
  [Char] -> Eff (er :& es) [Char]
forall a. a -> Eff (er :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
"End of loop"

effIOExample :: IO ()
effIOExample :: IO ()
effIOExample = (forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) ())
-> IO ()
forall a.
(forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a)
-> IO a
runEff ((forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) ())
 -> IO ())
-> (forall (e :: Effects) (es :: Effects).
    IOE e -> Eff (e :& es) ())
-> IO ()
forall a b. (a -> b) -> a -> b
$ \IOE e
io -> do
  IOE e -> IO () -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io ([Char] -> IO ()
putStrLn [Char]
"Hello world!")

example1_ :: (Int, Int)
example1_ :: (Int, Int)
example1_ =
  let example1 :: Int -> Int
      example1 :: Int -> Int
example1 Int
n = (forall (es :: Effects). Eff es Int) -> Int
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es Int) -> Int)
-> (forall (es :: Effects). Eff es Int) -> Int
forall a b. (a -> b) -> a -> b
$ Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
n ((forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
 -> Eff es Int)
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
        Int
n' <- State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st
        Bool -> Eff (st :& es) () -> Eff (st :& es) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
10) (Eff (st :& es) () -> Eff (st :& es) ())
-> Eff (st :& es) () -> Eff (st :& es) ()
forall a b. (a -> b) -> a -> b
$
          State Int st -> Int -> Eff (st :& es) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int st
st (Int
n' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10)
        State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st
   in (Int -> Int
example1 Int
5, Int -> Int
example1 Int
12)

example2_ :: ((Int, Int), (Int, Int))
example2_ :: ((Int, Int), (Int, Int))
example2_ =
  let example2 :: (Int, Int) -> (Int, Int)
      example2 :: (Int, Int) -> (Int, Int)
example2 (Int
m, Int
n) = (forall (es :: Effects). Eff es (Int, Int)) -> (Int, Int)
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es (Int, Int)) -> (Int, Int))
-> (forall (es :: Effects). Eff es (Int, Int)) -> (Int, Int)
forall a b. (a -> b) -> a -> b
$
        Int
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& es) (Int, Int))
-> Eff es (Int, Int)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
m ((forall {st :: Effects}.
  State Int st -> Eff (st :& es) (Int, Int))
 -> Eff es (Int, Int))
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& es) (Int, Int))
-> Eff es (Int, Int)
forall a b. (a -> b) -> a -> b
$ \State Int st
sm -> do
          Int
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (st :& es)) (Int, Int))
-> Eff (st :& es) (Int, Int)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
n ((forall {st :: Effects}.
  State Int st -> Eff (st :& (st :& es)) (Int, Int))
 -> Eff (st :& es) (Int, Int))
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (st :& es)) (Int, Int))
-> Eff (st :& es) (Int, Int)
forall a b. (a -> b) -> a -> b
$ \State Int st
sn -> do
            do
              Int
n' <- State Int st -> Eff (st :& (st :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
sn
              Int
m' <- State Int st -> Eff (st :& (st :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
sm

              if Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
m'
                then State Int st -> Int -> Eff (st :& (st :& es)) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int st
sn (Int
n' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10)
                else State Int st -> Int -> Eff (st :& (st :& es)) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int st
sm (Int
m' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10)

            Int
n' <- State Int st -> Eff (st :& (st :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
sn
            Int
m' <- State Int st -> Eff (st :& (st :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
sm

            (Int, Int) -> Eff (st :& (st :& es)) (Int, Int)
forall a. a -> Eff (st :& (st :& es)) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
n', Int
m')
   in ((Int, Int) -> (Int, Int)
example2 (Int
5, Int
10), (Int, Int) -> (Int, Int)
example2 (Int
12, Int
5))

example3' :: Int -> Either String Int
example3' :: Int -> Either [Char] Int
example3' Int
n = (forall (es :: Effects). Eff es (Either [Char] Int))
-> Either [Char] Int
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es (Either [Char] Int))
 -> Either [Char] Int)
-> (forall (es :: Effects). Eff es (Either [Char] Int))
-> Either [Char] Int
forall a b. (a -> b) -> a -> b
$
  (forall (ex :: Effects). Exception [Char] ex -> Eff (ex :& es) Int)
-> Eff es (Either [Char] Int)
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception [Char] ex -> Eff (ex :& es) Int)
 -> Eff es (Either [Char] Int))
-> (forall (ex :: Effects).
    Exception [Char] ex -> Eff (ex :& es) Int)
-> Eff es (Either [Char] Int)
forall a b. (a -> b) -> a -> b
$ \Exception [Char] ex
ex -> do
    Int
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (ex :& es)) Int)
-> Eff (ex :& es) Int
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
0 ((forall {st :: Effects}.
  State Int st -> Eff (st :& (ex :& es)) Int)
 -> Eff (ex :& es) Int)
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (ex :& es)) Int)
-> Eff (ex :& es) Int
forall a b. (a -> b) -> a -> b
$ \State Int st
total -> do
      [Int]
-> (Int -> Eff (st :& (ex :& es)) ()) -> Eff (st :& (ex :& es)) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Int
1 .. Int
n] ((Int -> Eff (st :& (ex :& es)) ()) -> Eff (st :& (ex :& es)) ())
-> (Int -> Eff (st :& (ex :& es)) ()) -> Eff (st :& (ex :& es)) ()
forall a b. (a -> b) -> a -> b
$ \Int
i -> do
        Int
soFar <- State Int st -> Eff (st :& (ex :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
total
        Bool -> Eff (st :& (ex :& es)) () -> Eff (st :& (ex :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
soFar Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
20) (Eff (st :& (ex :& es)) () -> Eff (st :& (ex :& es)) ())
-> Eff (st :& (ex :& es)) () -> Eff (st :& (ex :& es)) ()
forall a b. (a -> b) -> a -> b
$ do
          Exception [Char] ex -> [Char] -> Eff (st :& (ex :& es)) ()
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception [Char] ex
ex ([Char]
"Became too big: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
soFar)
        State Int st -> Int -> Eff (st :& (ex :& es)) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int st
total (Int
soFar Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i)

      State Int st -> Eff (st :& (ex :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
total

-- Count non-empty lines from stdin, and print a friendly message,
-- until we see "STOP".
example3_ :: IO ()
example3_ :: IO ()
example3_ = (forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) ())
-> IO ()
forall a.
(forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a)
-> IO a
runEff ((forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) ())
 -> IO ())
-> (forall (e :: Effects) (es :: Effects).
    IOE e -> Eff (e :& es) ())
-> IO ()
forall a b. (a -> b) -> a -> b
$ \IOE e
io -> do
  let getLineUntilStop :: Coroutine [Char] () e1 -> Eff es ()
getLineUntilStop Coroutine [Char] () e1
y = (forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
forall (es :: Effects).
(forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
withJump ((forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ())
-> (forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
forall a b. (a -> b) -> a -> b
$ \Jump j
stop -> Eff (j :& es) () -> Eff (j :& es) ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (Eff (j :& es) () -> Eff (j :& es) ())
-> Eff (j :& es) () -> Eff (j :& es) ()
forall a b. (a -> b) -> a -> b
$ do
        [Char]
line <- IOE e -> IO [Char] -> Eff (j :& es) [Char]
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io IO [Char]
getLine
        Bool -> Eff (j :& es) () -> Eff (j :& es) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Char]
line [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"STOP") (Eff (j :& es) () -> Eff (j :& es) ())
-> Eff (j :& es) () -> Eff (j :& es) ()
forall a b. (a -> b) -> a -> b
$
          Jump j -> Eff (j :& es) ()
forall (j :: Effects) (es :: Effects) a.
(j :> es) =>
Jump j -> Eff es a
jumpTo Jump j
stop
        Coroutine [Char] () e1 -> [Char] -> Eff (j :& es) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Coroutine [Char] () e1
y [Char]
line

      nonEmptyLines :: Stream [Char] e2 -> Eff es ()
nonEmptyLines =
        ([Char] -> Maybe [Char])
-> (forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) ())
-> Stream [Char] e2
-> Eff es ()
forall (e2 :: Effects) (es :: Effects) a b r.
(e2 :> es) =>
(a -> Maybe b)
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream b e2
-> Eff es r
mapMaybe
          ( \case
              [Char]
"" -> Maybe [Char]
forall a. Maybe a
Nothing
              [Char]
line -> [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
line
          )
          Coroutine [Char] () e1 -> Eff (e1 :& es) ()
forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) ()
forall {es :: Effects} {e1 :: Effects}.
(e :> es, e1 :> es) =>
Coroutine [Char] () e1 -> Eff es ()
getLineUntilStop

      enumeratedLines :: Stream (Int, [Char]) e2 -> Eff es ()
enumeratedLines = Int
-> (forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) ())
-> Stream (Int, [Char]) e2
-> Eff es ()
forall (e2 :: Effects) (es :: Effects) a r.
(e2 :> es) =>
Int
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream (Int, a) e2
-> Eff es r
enumerateFrom Int
1 Stream [Char] e1 -> Eff (e1 :& es) ()
forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) ()
forall {e2 :: Effects} {es :: Effects}.
(e2 :> es, e :> es) =>
Stream [Char] e2 -> Eff es ()
nonEmptyLines

      formattedLines :: Stream [Char] e2 -> Eff es ()
formattedLines =
        ((Int, [Char]) -> [Char])
-> (forall (e1 :: Effects).
    Stream (Int, [Char]) e1 -> Eff (e1 :& es) ())
-> Stream [Char] e2
-> Eff es ()
forall (e2 :: Effects) (es :: Effects) a b r.
(e2 :> es) =>
(a -> b)
-> (forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Stream b e2
-> Eff es r
mapStream
          (\(Int
i, [Char]
line) -> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
". Hello! You said " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
line)
          Stream (Int, [Char]) e1 -> Eff (e1 :& es) ()
forall (e1 :: Effects).
Stream (Int, [Char]) e1 -> Eff (e1 :& es) ()
forall {e2 :: Effects} {es :: Effects}.
(e2 :> es, e :> es) =>
Stream (Int, [Char]) e2 -> Eff es ()
enumeratedLines

  (forall (e1 :: Effects).
 Coroutine [Char] () e1 -> Eff (e1 :& (e :& es)) ())
-> ([Char] -> Eff (e :& es) ()) -> Eff (e :& es) ()
forall a b (es :: Effects) r.
(forall (e1 :: Effects). Coroutine a b e1 -> Eff (e1 :& es) r)
-> (a -> Eff es b) -> Eff es r
forEach Stream [Char] e1 -> Eff (e1 :& (e :& es)) ()
forall (e1 :: Effects).
Coroutine [Char] () e1 -> Eff (e1 :& (e :& es)) ()
forall {e2 :: Effects} {es :: Effects}.
(e2 :> es, e :> es) =>
Stream [Char] e2 -> Eff es ()
formattedLines (([Char] -> Eff (e :& es) ()) -> Eff (e :& es) ())
-> ([Char] -> Eff (e :& es) ()) -> Eff (e :& es) ()
forall a b. (a -> b) -> a -> b
$ \[Char]
line -> IOE e -> IO () -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io ([Char] -> IO ()
putStrLn [Char]
line)

-- Count the number of (strictly) positives and (strictly) negatives
-- in a list, unless we see a zero, in which case we bail with an
-- error message.
countPositivesNegatives :: [Int] -> String
countPositivesNegatives :: [Int] -> [Char]
countPositivesNegatives [Int]
is = (forall (es :: Effects). Eff es [Char]) -> [Char]
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es [Char]) -> [Char])
-> (forall (es :: Effects). Eff es [Char]) -> [Char]
forall a b. (a -> b) -> a -> b
$
  Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) [Char])
-> Eff es [Char]
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState (Int
0 :: Int) ((forall {st :: Effects}. State Int st -> Eff (st :& es) [Char])
 -> Eff es [Char])
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) [Char])
-> Eff es [Char]
forall a b. (a -> b) -> a -> b
$ \State Int st
positives -> do
    Either () [Char]
r <- (forall (ex :: Effects).
 Exception () ex -> Eff (ex :& (st :& es)) [Char])
-> Eff (st :& es) (Either () [Char])
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception () ex -> Eff (ex :& (st :& es)) [Char])
 -> Eff (st :& es) (Either () [Char]))
-> (forall (ex :: Effects).
    Exception () ex -> Eff (ex :& (st :& es)) [Char])
-> Eff (st :& es) (Either () [Char])
forall a b. (a -> b) -> a -> b
$ \Exception () ex
ex ->
      Int
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (ex :& (st :& es))) [Char])
-> Eff (ex :& (st :& es)) [Char]
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState (Int
0 :: Int) ((forall {st :: Effects}.
  State Int st -> Eff (st :& (ex :& (st :& es))) [Char])
 -> Eff (ex :& (st :& es)) [Char])
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (ex :& (st :& es))) [Char])
-> Eff (ex :& (st :& es)) [Char]
forall a b. (a -> b) -> a -> b
$ \State Int st
negatives -> do
        [Int]
-> (Int -> Eff (st :& (ex :& (st :& es))) ())
-> Eff (st :& (ex :& (st :& es))) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Int]
is ((Int -> Eff (st :& (ex :& (st :& es))) ())
 -> Eff (st :& (ex :& (st :& es))) ())
-> (Int -> Eff (st :& (ex :& (st :& es))) ())
-> Eff (st :& (ex :& (st :& es))) ()
forall a b. (a -> b) -> a -> b
$ \Int
i -> do
          case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
i Int
0 of
            Ordering
GT -> State Int st -> (Int -> Int) -> Eff (st :& (ex :& (st :& es))) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int st
positives (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
            Ordering
EQ -> Exception () ex -> () -> Eff (st :& (ex :& (st :& es))) ()
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception () ex
ex ()
            Ordering
LT -> State Int st -> (Int -> Int) -> Eff (st :& (ex :& (st :& es))) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int st
negatives (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

        Int
p <- State Int st -> Eff (st :& (ex :& (st :& es))) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
positives
        Int
n <- State Int st -> Eff (st :& (ex :& (st :& es))) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
negatives

        [Char] -> Eff (st :& (ex :& (st :& es))) [Char]
forall a. a -> Eff (st :& (ex :& (st :& es))) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char] -> Eff (st :& (ex :& (st :& es))) [Char])
-> [Char] -> Eff (st :& (ex :& (st :& es))) [Char]
forall a b. (a -> b) -> a -> b
$
          [Char]
"Positives: "
            [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
p
            [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
", negatives "
            [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n

    case Either () [Char]
r of
      Right [Char]
r' -> [Char] -> Eff (st :& es) [Char]
forall a. a -> Eff (st :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
r'
      Left () -> do
        Int
p <- State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
positives
        [Char] -> Eff (st :& es) [Char]
forall a. a -> Eff (st :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Char] -> Eff (st :& es) [Char])
-> [Char] -> Eff (st :& es) [Char]
forall a b. (a -> b) -> a -> b
$
          [Char]
"We saw a zero, but before that there were "
            [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
p
            [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" positives"

-- How to make compound effects

type MyHandle = Compound (State Int) (Exception String)

myInc :: (e :> es) => MyHandle e -> Eff es ()
myInc :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
MyHandle e -> Eff es ()
myInc MyHandle e
h = MyHandle e
-> (forall (e1 :: Effects) (e2 :: Effects).
    (e1 :> es, e2 :> es) =>
    State Int e1 -> Exception [Char] e2 -> Eff es ())
-> Eff es ()
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e :: Effects)
       (es :: Effects) r.
(e :> es) =>
Compound h1 h2 e
-> (forall (e1 :: Effects) (e2 :: Effects).
    (e1 :> es, e2 :> es) =>
    h1 e1 -> h2 e2 -> Eff es r)
-> Eff es r
withCompound MyHandle e
h (\State Int e1
s Exception [Char] e2
_ -> State Int e1 -> (Int -> Int) -> Eff es ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int e1
s (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))

myBail :: (e :> es) => MyHandle e -> Eff es r
myBail :: forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
MyHandle e -> Eff es r
myBail MyHandle e
h = MyHandle e
-> (forall {e1 :: Effects} {e2 :: Effects}.
    (e1 :> es, e2 :> es) =>
    State Int e1 -> Exception [Char] e2 -> Eff es r)
-> Eff es r
forall (h1 :: Effects -> *) (h2 :: Effects -> *) (e :: Effects)
       (es :: Effects) r.
(e :> es) =>
Compound h1 h2 e
-> (forall (e1 :: Effects) (e2 :: Effects).
    (e1 :> es, e2 :> es) =>
    h1 e1 -> h2 e2 -> Eff es r)
-> Eff es r
withCompound MyHandle e
h ((forall {e1 :: Effects} {e2 :: Effects}.
  (e1 :> es, e2 :> es) =>
  State Int e1 -> Exception [Char] e2 -> Eff es r)
 -> Eff es r)
-> (forall {e1 :: Effects} {e2 :: Effects}.
    (e1 :> es, e2 :> es) =>
    State Int e1 -> Exception [Char] e2 -> Eff es r)
-> Eff es r
forall a b. (a -> b) -> a -> b
$ \State Int e1
s Exception [Char] e2
e -> do
  Int
i <- State Int e1 -> Eff es Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int e1
s
  Exception [Char] e2 -> [Char] -> Eff es r
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception [Char] e2
e ([Char]
"Current state was: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i)

runMyHandle ::
  (forall e. MyHandle e -> Eff (e :& es) a) ->
  Eff es (Either String (a, Int))
runMyHandle :: forall (es :: Effects) a.
(forall (e :: Effects). MyHandle e -> Eff (e :& es) a)
-> Eff es (Either [Char] (a, Int))
runMyHandle forall (e :: Effects). MyHandle e -> Eff (e :& es) a
f =
  (forall (ex :: Effects).
 Exception [Char] ex -> Eff (ex :& es) (a, Int))
-> Eff es (Either [Char] (a, Int))
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception [Char] ex -> Eff (ex :& es) (a, Int))
 -> Eff es (Either [Char] (a, Int)))
-> (forall (ex :: Effects).
    Exception [Char] ex -> Eff (ex :& es) (a, Int))
-> Eff es (Either [Char] (a, Int))
forall a b. (a -> b) -> a -> b
$ \Exception [Char] ex
e -> do
    Int
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (ex :& es)) a)
-> Eff (ex :& es) (a, Int)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState Int
0 ((forall {st :: Effects}. State Int st -> Eff (st :& (ex :& es)) a)
 -> Eff (ex :& es) (a, Int))
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (ex :& es)) a)
-> Eff (ex :& es) (a, Int)
forall a b. (a -> b) -> a -> b
$ \State Int st
s -> do
      State Int st
-> Exception [Char] ex
-> (forall (e :: Effects). MyHandle e -> Eff (e :& es) a)
-> Eff (st :& (ex :& es)) a
forall (e1 :: Effects -> *) (s1 :: Effects) (e2 :: Effects -> *)
       (s2 :: Effects) (es :: Effects) r.
e1 s1
-> e2 s2
-> (forall (es' :: Effects).
    Compound e1 e2 es' -> Eff (es' :& es) r)
-> Eff (s1 :& (s2 :& es)) r
runCompound State Int st
s Exception [Char] ex
e MyHandle es' -> Eff (es' :& es) a
forall (e :: Effects). MyHandle e -> Eff (e :& es) a
f

compoundExample :: Either String (a, Int)
compoundExample :: forall a. Either [Char] (a, Int)
compoundExample = (forall (es :: Effects). Eff es (Either [Char] (a, Int)))
-> Either [Char] (a, Int)
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es (Either [Char] (a, Int)))
 -> Either [Char] (a, Int))
-> (forall (es :: Effects). Eff es (Either [Char] (a, Int)))
-> Either [Char] (a, Int)
forall a b. (a -> b) -> a -> b
$ (forall (e :: Effects). MyHandle e -> Eff (e :& es) a)
-> Eff es (Either [Char] (a, Int))
forall (es :: Effects) a.
(forall (e :: Effects). MyHandle e -> Eff (e :& es) a)
-> Eff es (Either [Char] (a, Int))
runMyHandle ((forall (e :: Effects). MyHandle e -> Eff (e :& es) a)
 -> Eff es (Either [Char] (a, Int)))
-> (forall (e :: Effects). MyHandle e -> Eff (e :& es) a)
-> Eff es (Either [Char] (a, Int))
forall a b. (a -> b) -> a -> b
$ \MyHandle e
h -> do
  MyHandle e -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
MyHandle e -> Eff es ()
myInc MyHandle e
h
  MyHandle e -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
MyHandle e -> Eff es ()
myInc MyHandle e
h
  MyHandle e -> Eff (e :& es) a
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
MyHandle e -> Eff es r
myBail MyHandle e
h

countExample :: IO ()
countExample :: IO ()
countExample = (forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) ())
-> IO ()
forall a.
(forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a)
-> IO a
runEff ((forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) ())
 -> IO ())
-> (forall (e :: Effects) (es :: Effects).
    IOE e -> Eff (e :& es) ())
-> IO ()
forall a b. (a -> b) -> a -> b
$ \IOE e
io -> do
  forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState @Int Int
0 ((forall {st :: Effects}. State Int st -> Eff (st :& (e :& es)) ())
 -> Eff (e :& es) ())
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (e :& es)) ())
-> Eff (e :& es) ()
forall a b. (a -> b) -> a -> b
$ \State Int st
sn -> do
    (forall (j :: Effects). Jump j -> Eff (j :& (st :& (e :& es))) ())
-> Eff (st :& (e :& es)) ()
forall (es :: Effects).
(forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
withJump ((forall (j :: Effects). Jump j -> Eff (j :& (st :& (e :& es))) ())
 -> Eff (st :& (e :& es)) ())
-> (forall (j :: Effects).
    Jump j -> Eff (j :& (st :& (e :& es))) ())
-> Eff (st :& (e :& es)) ()
forall a b. (a -> b) -> a -> b
$ \Jump j
break -> Eff (j :& (st :& (e :& es))) () -> Eff (j :& (st :& (e :& es))) ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (Eff (j :& (st :& (e :& es))) ()
 -> Eff (j :& (st :& (e :& es))) ())
-> Eff (j :& (st :& (e :& es))) ()
-> Eff (j :& (st :& (e :& es))) ()
forall a b. (a -> b) -> a -> b
$ do
      Int
n <- State Int st -> Eff (j :& (st :& (e :& es))) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
sn
      Bool
-> Eff (j :& (st :& (e :& es))) ()
-> Eff (j :& (st :& (e :& es))) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10) (Jump j -> Eff (j :& (st :& (e :& es))) ()
forall (j :: Effects) (es :: Effects) a.
(j :> es) =>
Jump j -> Eff es a
jumpTo Jump j
break)
      IOE e -> IO () -> Eff (j :& (st :& (e :& es))) ()
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e
io (Int -> IO ()
forall a. Show a => a -> IO ()
print Int
n)
      State Int st -> (Int -> Int) -> Eff (j :& (st :& (e :& es))) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int st
sn (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

writerExample1 :: Bool
writerExample1 :: Bool
writerExample1 = Any -> Bool
getAny (Any -> Bool) -> Any -> Bool
forall a b. (a -> b) -> a -> b
$ (forall (es :: Effects). Eff es Any) -> Any
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es Any) -> Any)
-> (forall (es :: Effects). Eff es Any) -> Any
forall a b. (a -> b) -> a -> b
$ (forall (e :: Effects). Writer Any e -> Eff (e :& es) ())
-> Eff es Any
forall w (es :: Effects) r.
Monoid w =>
(forall (e :: Effects). Writer w e -> Eff (e :& es) r) -> Eff es w
execWriter ((forall (e :: Effects). Writer Any e -> Eff (e :& es) ())
 -> Eff es Any)
-> (forall (e :: Effects). Writer Any e -> Eff (e :& es) ())
-> Eff es Any
forall a b. (a -> b) -> a -> b
$ \Writer Any e
w -> do
  [Any] -> (Any -> Eff (e :& es) ()) -> Eff (e :& es) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [] ((Any -> Eff (e :& es) ()) -> Eff (e :& es) ())
-> (Any -> Eff (e :& es) ()) -> Eff (e :& es) ()
forall a b. (a -> b) -> a -> b
$ \Any
_ -> Writer Any e -> Any -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects) w.
(e :> es) =>
Writer w e -> w -> Eff es ()
tell Writer Any e
w (Bool -> Any
Any Bool
True)

writerExample2 :: Bool
writerExample2 :: Bool
writerExample2 = Any -> Bool
getAny (Any -> Bool) -> Any -> Bool
forall a b. (a -> b) -> a -> b
$ (forall (es :: Effects). Eff es Any) -> Any
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es Any) -> Any)
-> (forall (es :: Effects). Eff es Any) -> Any
forall a b. (a -> b) -> a -> b
$ (forall (e :: Effects). Writer Any e -> Eff (e :& es) ())
-> Eff es Any
forall w (es :: Effects) r.
Monoid w =>
(forall (e :: Effects). Writer w e -> Eff (e :& es) r) -> Eff es w
execWriter ((forall (e :: Effects). Writer Any e -> Eff (e :& es) ())
 -> Eff es Any)
-> (forall (e :: Effects). Writer Any e -> Eff (e :& es) ())
-> Eff es Any
forall a b. (a -> b) -> a -> b
$ \Writer Any e
w -> do
  [Integer] -> (Integer -> Eff (e :& es) ()) -> Eff (e :& es) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Integer
1 .. Integer
10] ((Integer -> Eff (e :& es) ()) -> Eff (e :& es) ())
-> (Integer -> Eff (e :& es) ()) -> Eff (e :& es) ()
forall a b. (a -> b) -> a -> b
$ \Integer
_ -> Writer Any e -> Any -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects) w.
(e :> es) =>
Writer w e -> w -> Eff es ()
tell Writer Any e
w (Bool -> Any
Any Bool
True)

while :: Eff es Bool -> Eff es a -> Eff es ()
while :: forall (es :: Effects) a. Eff es Bool -> Eff es a -> Eff es ()
while Eff es Bool
condM Eff es a
body =
  (forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
forall (es :: Effects).
(forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
withJump ((forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ())
-> (forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
forall a b. (a -> b) -> a -> b
$ \Jump j
break_ -> do
    Eff (j :& es) a -> Eff (j :& es) ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (Eff (j :& es) a -> Eff (j :& es) ())
-> Eff (j :& es) a -> Eff (j :& es) ()
forall a b. (a -> b) -> a -> b
$ do
      Bool
cond <- Eff es Bool -> Eff (j :& es) Bool
forall (b :: Effects) r (c1 :: Effects). Eff b r -> Eff (c1 :& b) r
insertFirst Eff es Bool
condM
      Bool -> Eff (j :& es) () -> Eff (j :& es) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
cond (Jump j -> Eff (j :& es) ()
forall (j :: Effects) (es :: Effects) a.
(j :> es) =>
Jump j -> Eff es a
jumpTo Jump j
break_)
      Eff es a -> Eff (j :& es) a
forall (b :: Effects) r (c1 :: Effects). Eff b r -> Eff (c1 :& b) r
insertFirst Eff es a
body

stateSourceExample :: Int
stateSourceExample :: Int
stateSourceExample = (forall (es :: Effects). Eff es Int) -> Int
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es Int) -> Int)
-> (forall (es :: Effects). Eff es Int) -> Int
forall a b. (a -> b) -> a -> b
$ (forall (e :: Effects). StateSource e -> Eff (e :& es) Int)
-> Eff es Int
forall (es :: Effects) a.
(forall (e :: Effects). StateSource e -> Eff (e :& es) a)
-> Eff es a
withStateSource ((forall (e :: Effects). StateSource e -> Eff (e :& es) Int)
 -> Eff es Int)
-> (forall (e :: Effects). StateSource e -> Eff (e :& es) Int)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \StateSource e
source -> do
  State Int e
n <- StateSource e -> Int -> Eff (e :& es) (State Int e)
forall (e :: Effects) s (es :: Effects).
StateSource e -> s -> Eff es (State s e)
newState StateSource e
source Int
5
  State Int e
total <- StateSource e -> Int -> Eff (e :& es) (State Int e)
forall (e :: Effects) s (es :: Effects).
StateSource e -> s -> Eff es (State s e)
newState StateSource e
source Int
0

  (forall (j :: Effects). Jump j -> Eff (j :& (e :& es)) ())
-> Eff (e :& es) ()
forall (es :: Effects).
(forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
withJump ((forall (j :: Effects). Jump j -> Eff (j :& (e :& es)) ())
 -> Eff (e :& es) ())
-> (forall (j :: Effects). Jump j -> Eff (j :& (e :& es)) ())
-> Eff (e :& es) ()
forall a b. (a -> b) -> a -> b
$ \Jump j
done -> Eff (j :& (e :& es)) () -> Eff (j :& (e :& es)) ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (Eff (j :& (e :& es)) () -> Eff (j :& (e :& es)) ())
-> Eff (j :& (e :& es)) () -> Eff (j :& (e :& es)) ()
forall a b. (a -> b) -> a -> b
$ do
    Int
n' <- State Int e -> Eff (j :& (e :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int e
n
    State Int e -> (Int -> Int) -> Eff (j :& (e :& es)) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int e
total (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n')
    Bool -> Eff (j :& (e :& es)) () -> Eff (j :& (e :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Eff (j :& (e :& es)) () -> Eff (j :& (e :& es)) ())
-> Eff (j :& (e :& es)) () -> Eff (j :& (e :& es)) ()
forall a b. (a -> b) -> a -> b
$ Jump j -> Eff (j :& (e :& es)) ()
forall (j :: Effects) (es :: Effects) a.
(j :> es) =>
Jump j -> Eff es a
jumpTo Jump j
done
    State Int e -> (Int -> Int) -> Eff (j :& (e :& es)) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int e
n (Int -> Int -> Int
forall a. Num a => a -> a -> a
subtract Int
1)

  State Int e -> Eff (e :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int e
total

incrementReadLine ::
  (e1 :> es, e2 :> es, e3 :> es) =>
  State Int e1 ->
  Exception String e2 ->
  IOE e3 ->
  Eff es ()
incrementReadLine :: forall (e1 :: Effects) (es :: Effects) (e2 :: Effects)
       (e3 :: Effects).
(e1 :> es, e2 :> es, e3 :> es) =>
State Int e1 -> Exception [Char] e2 -> IOE e3 -> Eff es ()
incrementReadLine State Int e1
state Exception [Char] e2
exception IOE e3
io = do
  (forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
forall (es :: Effects).
(forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
withJump ((forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ())
-> (forall (j :: Effects). Jump j -> Eff (j :& es) ()) -> Eff es ()
forall a b. (a -> b) -> a -> b
$ \Jump j
break -> Eff (j :& es) () -> Eff (j :& es) ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (Eff (j :& es) () -> Eff (j :& es) ())
-> Eff (j :& es) () -> Eff (j :& es) ()
forall a b. (a -> b) -> a -> b
$ do
    [Char]
line <- IOE e3 -> IO [Char] -> Eff (j :& es) [Char]
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e3
io IO [Char]
getLine
    Int
i <- case [Char] -> Maybe Int
forall a. Read a => [Char] -> Maybe a
readMaybe [Char]
line of
      Maybe Int
Nothing ->
        Exception [Char] e2 -> [Char] -> Eff (j :& es) Int
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception [Char] e2
exception ([Char]
"Couldn't read: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
line)
      Just Int
i ->
        Int -> Eff (j :& es) Int
forall a. a -> Eff (j :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
i

    Bool -> Eff (j :& es) () -> Eff (j :& es) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Eff (j :& es) () -> Eff (j :& es) ())
-> Eff (j :& es) () -> Eff (j :& es) ()
forall a b. (a -> b) -> a -> b
$
      Jump j -> Eff (j :& es) ()
forall (j :: Effects) (es :: Effects) a.
(j :> es) =>
Jump j -> Eff es a
jumpTo Jump j
break

    State Int e1 -> (Int -> Int) -> Eff (j :& es) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int e1
state (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i)

runIncrementReadLine :: IO (Either String Int)
runIncrementReadLine :: IO (Either [Char] Int)
runIncrementReadLine = (forall (e :: Effects) (es :: Effects).
 IOE e -> Eff (e :& es) (Either [Char] Int))
-> IO (Either [Char] Int)
forall a.
(forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a)
-> IO a
runEff ((forall (e :: Effects) (es :: Effects).
  IOE e -> Eff (e :& es) (Either [Char] Int))
 -> IO (Either [Char] Int))
-> (forall (e :: Effects) (es :: Effects).
    IOE e -> Eff (e :& es) (Either [Char] Int))
-> IO (Either [Char] Int)
forall a b. (a -> b) -> a -> b
$ \IOE e
io -> do
  (forall (ex :: Effects).
 Exception [Char] ex -> Eff (ex :& (e :& es)) Int)
-> Eff (e :& es) (Either [Char] Int)
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception [Char] ex -> Eff (ex :& (e :& es)) Int)
 -> Eff (e :& es) (Either [Char] Int))
-> (forall (ex :: Effects).
    Exception [Char] ex -> Eff (ex :& (e :& es)) Int)
-> Eff (e :& es) (Either [Char] Int)
forall a b. (a -> b) -> a -> b
$ \Exception [Char] ex
exception -> do
    ((), Int
r) <- Int
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (ex :& (e :& es))) ())
-> Eff (ex :& (e :& es)) ((), Int)
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es (a, s)
runState Int
0 ((forall {st :: Effects}.
  State Int st -> Eff (st :& (ex :& (e :& es))) ())
 -> Eff (ex :& (e :& es)) ((), Int))
-> (forall {st :: Effects}.
    State Int st -> Eff (st :& (ex :& (e :& es))) ())
-> Eff (ex :& (e :& es)) ((), Int)
forall a b. (a -> b) -> a -> b
$ \State Int st
state -> do
      State Int st
-> Exception [Char] ex -> IOE e -> Eff (st :& (ex :& (e :& es))) ()
forall (e1 :: Effects) (es :: Effects) (e2 :: Effects)
       (e3 :: Effects).
(e1 :> es, e2 :> es, e3 :> es) =>
State Int e1 -> Exception [Char] e2 -> IOE e3 -> Eff es ()
incrementReadLine State Int st
state Exception [Char] ex
exception IOE e
io
    Int -> Eff (ex :& (e :& es)) Int
forall a. a -> Eff (ex :& (e :& es)) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
r

-- Counter 1

newtype Counter1 e = MkCounter1 (State Int e)

incCounter1 :: (e :> es) => Counter1 e -> Eff es ()
incCounter1 :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter1 e -> Eff es ()
incCounter1 (MkCounter1 State Int e
st) = State Int e -> (Int -> Int) -> Eff es ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State Int e
st (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

runCounter1 ::
  (forall e. Counter1 e -> Eff (e :& es) r) ->
  Eff es Int
runCounter1 :: forall (es :: Effects) r.
(forall (e :: Effects). Counter1 e -> Eff (e :& es) r)
-> Eff es Int
runCounter1 forall (e :: Effects). Counter1 e -> Eff (e :& es) r
k =
  Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
0 ((forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
 -> Eff es Int)
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
    r
_ <- Counter1 st -> Eff (st :& es) r
forall (e :: Effects). Counter1 e -> Eff (e :& es) r
k (State Int st -> Counter1 st
forall (e :: Effects). State Int e -> Counter1 e
MkCounter1 State Int st
st)
    State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st

exampleCounter1 :: Int
exampleCounter1 :: Int
exampleCounter1 = (forall (es :: Effects). Eff es Int) -> Int
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es Int) -> Int)
-> (forall (es :: Effects). Eff es Int) -> Int
forall a b. (a -> b) -> a -> b
$ (forall (e :: Effects). Counter1 e -> Eff (e :& es) ())
-> Eff es Int
forall (es :: Effects) r.
(forall (e :: Effects). Counter1 e -> Eff (e :& es) r)
-> Eff es Int
runCounter1 ((forall (e :: Effects). Counter1 e -> Eff (e :& es) ())
 -> Eff es Int)
-> (forall (e :: Effects). Counter1 e -> Eff (e :& es) ())
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \Counter1 e
c -> do
  Counter1 e -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter1 e -> Eff es ()
incCounter1 Counter1 e
c
  Counter1 e -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter1 e -> Eff es ()
incCounter1 Counter1 e
c
  Counter1 e -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter1 e -> Eff es ()
incCounter1 Counter1 e
c

-- > exampeleCounter1
-- 3

-- Counter 2

data Counter2 e1 e2 = MkCounter2 (State Int e1) (Exception () e2)

incCounter2 :: (e1 :> es, e2 :> es) => Counter2 e1 e2 -> Eff es ()
incCounter2 :: forall (e1 :: Effects) (es :: Effects) (e2 :: Effects).
(e1 :> es, e2 :> es) =>
Counter2 e1 e2 -> Eff es ()
incCounter2 (MkCounter2 State Int e1
st Exception () e2
ex) = do
  Int
count <- State Int e1 -> Eff es Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int e1
st
  Bool -> Eff es () -> Eff es ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10) (Eff es () -> Eff es ()) -> Eff es () -> Eff es ()
forall a b. (a -> b) -> a -> b
$
    Exception () e2 -> () -> Eff es ()
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception () e2
ex ()
  State Int e1 -> Int -> Eff es ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int e1
st (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

runCounter2 ::
  (forall e1 e2. Counter2 e1 e2 -> Eff (e2 :& e1 :& es) r) ->
  Eff es Int
runCounter2 :: forall (es :: Effects) r.
(forall (e1 :: Effects) (e2 :: Effects).
 Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) r)
-> Eff es Int
runCounter2 forall (e1 :: Effects) (e2 :: Effects).
Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) r
k =
  Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
0 ((forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
 -> Eff es Int)
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
    Either () r
_ <- (forall (ex :: Effects).
 Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception () ex -> Eff (ex :& (st :& es)) r)
 -> Eff (st :& es) (Either () r))
-> (forall (ex :: Effects).
    Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall a b. (a -> b) -> a -> b
$ \Exception () ex
ex -> do
      Counter2 st ex -> Eff (ex :& (st :& es)) r
forall (e1 :: Effects) (e2 :: Effects).
Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) r
k (State Int st -> Exception () ex -> Counter2 st ex
forall (e1 :: Effects) (e2 :: Effects).
State Int e1 -> Exception () e2 -> Counter2 e1 e2
MkCounter2 State Int st
st Exception () ex
ex)
    State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st

exampleCounter2 :: Int
exampleCounter2 :: Int
exampleCounter2 = (forall (es :: Effects). Eff es Int) -> Int
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es Int) -> Int)
-> (forall (es :: Effects). Eff es Int) -> Int
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects) (e2 :: Effects).
 Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) Any)
-> Eff es Int
forall (es :: Effects) r.
(forall (e1 :: Effects) (e2 :: Effects).
 Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) r)
-> Eff es Int
runCounter2 ((forall (e1 :: Effects) (e2 :: Effects).
  Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) Any)
 -> Eff es Int)
-> (forall (e1 :: Effects) (e2 :: Effects).
    Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) Any)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \Counter2 e1 e2
c ->
  Eff (e2 :& (e1 :& es)) () -> Eff (e2 :& (e1 :& es)) Any
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (Eff (e2 :& (e1 :& es)) () -> Eff (e2 :& (e1 :& es)) Any)
-> Eff (e2 :& (e1 :& es)) () -> Eff (e2 :& (e1 :& es)) Any
forall a b. (a -> b) -> a -> b
$
    Counter2 e1 e2 -> Eff (e2 :& (e1 :& es)) ()
forall (e1 :: Effects) (es :: Effects) (e2 :: Effects).
(e1 :> es, e2 :> es) =>
Counter2 e1 e2 -> Eff es ()
incCounter2 Counter2 e1 e2
c

-- > exampleCounter2
-- 10

-- Counter 3

data Counter3 e = MkCounter3 (State Int e) (Exception () e)

incCounter3 :: (e :> es) => Counter3 e -> Eff es ()
incCounter3 :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter3 e -> Eff es ()
incCounter3 (MkCounter3 State Int e
st Exception () e
ex) = do
  Int
count <- State Int e -> Eff es Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int e
st
  Bool -> Eff es () -> Eff es ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10) (Eff es () -> Eff es ()) -> Eff es () -> Eff es ()
forall a b. (a -> b) -> a -> b
$
    Exception () e -> () -> Eff es ()
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception () e
ex ()
  State Int e -> Int -> Eff es ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int e
st (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

runCounter3 ::
  (forall e. Counter3 e -> Eff (e :& es) r) ->
  Eff es Int
runCounter3 :: forall (es :: Effects) r.
(forall (e :: Effects). Counter3 e -> Eff (e :& es) r)
-> Eff es Int
runCounter3 forall (e :: Effects). Counter3 e -> Eff (e :& es) r
k =
  Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
0 ((forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
 -> Eff es Int)
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
    Either () r
_ <- (forall (ex :: Effects).
 Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception () ex -> Eff (ex :& (st :& es)) r)
 -> Eff (st :& es) (Either () r))
-> (forall (ex :: Effects).
    Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall a b. (a -> b) -> a -> b
$ \Exception () ex
ex -> do
      (Counter3 (ex :& (st :& es)) -> Eff ((ex :& (st :& es)) :& es) r)
-> Counter3 (ex :& (st :& es)) -> Eff (ex :& (st :& es)) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn Counter3 (ex :& (st :& es)) -> Eff ((ex :& (st :& es)) :& es) r
forall (e :: Effects). Counter3 e -> Eff (e :& es) r
k (State Int (ex :& (st :& es))
-> Exception () (ex :& (st :& es)) -> Counter3 (ex :& (st :& es))
forall (e :: Effects). State Int e -> Exception () e -> Counter3 e
MkCounter3 (State Int st -> State Int (ex :& (st :& es))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
State Int e -> State Int es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle State Int st
st) (Exception () ex -> Exception () (ex :& (st :& es))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Exception () e -> Exception () es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle Exception () ex
ex))
    State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st

exampleCounter3 :: Int
exampleCounter3 :: Int
exampleCounter3 = (forall (es :: Effects). Eff es Int) -> Int
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es Int) -> Int)
-> (forall (es :: Effects). Eff es Int) -> Int
forall a b. (a -> b) -> a -> b
$ (forall (e :: Effects). Counter3 e -> Eff (e :& es) Any)
-> Eff es Int
forall (es :: Effects) r.
(forall (e :: Effects). Counter3 e -> Eff (e :& es) r)
-> Eff es Int
runCounter3 ((forall (e :: Effects). Counter3 e -> Eff (e :& es) Any)
 -> Eff es Int)
-> (forall (e :: Effects). Counter3 e -> Eff (e :& es) Any)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \Counter3 e
c ->
  Eff (e :& es) () -> Eff (e :& es) Any
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (Eff (e :& es) () -> Eff (e :& es) Any)
-> Eff (e :& es) () -> Eff (e :& es) Any
forall a b. (a -> b) -> a -> b
$
    Counter3 e -> Eff (e :& es) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter3 e -> Eff es ()
incCounter3 Counter3 e
c

-- > exampleCounter3
-- 10

-- Counter 4

data Counter4 e
  = MkCounter4 (State Int e) (Exception () e) (Stream String e)

incCounter4 :: (e :> es) => Counter4 e -> Eff es ()
incCounter4 :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter4 e -> Eff es ()
incCounter4 (MkCounter4 State Int e
st Exception () e
ex Stream [Char] e
y) = do
  Int
count <- State Int e -> Eff es Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int e
st

  Bool -> Eff es () -> Eff es ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int -> Bool
forall a. Integral a => a -> Bool
even Int
count) (Eff es () -> Eff es ()) -> Eff es () -> Eff es ()
forall a b. (a -> b) -> a -> b
$
    Stream [Char] e -> [Char] -> Eff es ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e
y [Char]
"Count was even"

  Bool -> Eff es () -> Eff es ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10) (Eff es () -> Eff es ()) -> Eff es () -> Eff es ()
forall a b. (a -> b) -> a -> b
$
    Exception () e -> () -> Eff es ()
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception () e
ex ()

  State Int e -> Int -> Eff es ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int e
st (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)

getCounter4 :: (e :> es) => Counter4 e -> String -> Eff es Int
getCounter4 :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter4 e -> [Char] -> Eff es Int
getCounter4 (MkCounter4 State Int e
st Exception () e
_ Stream [Char] e
y) [Char]
msg = do
  Stream [Char] e -> [Char] -> Eff es ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e
y [Char]
msg
  State Int e -> Eff es Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int e
st

runCounter4 ::
  (e1 :> es) =>
  Stream String e1 ->
  (forall e. Counter4 e -> Eff (e :& es) r) ->
  Eff es Int
runCounter4 :: forall (e1 :: Effects) (es :: Effects) r.
(e1 :> es) =>
Stream [Char] e1
-> (forall (e :: Effects). Counter4 e -> Eff (e :& es) r)
-> Eff es Int
runCounter4 Stream [Char] e1
y forall (e :: Effects). Counter4 e -> Eff (e :& es) r
k =
  Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
0 ((forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
 -> Eff es Int)
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
    Either () r
_ <- (forall (ex :: Effects).
 Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception () ex -> Eff (ex :& (st :& es)) r)
 -> Eff (st :& es) (Either () r))
-> (forall (ex :: Effects).
    Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall a b. (a -> b) -> a -> b
$ \Exception () ex
ex -> do
      (Counter4 (ex :& (st :& es)) -> Eff ((ex :& (st :& es)) :& es) r)
-> Counter4 (ex :& (st :& es)) -> Eff (ex :& (st :& es)) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn Counter4 (ex :& (st :& es)) -> Eff ((ex :& (st :& es)) :& es) r
forall (e :: Effects). Counter4 e -> Eff (e :& es) r
k (State Int (ex :& (st :& es))
-> Exception () (ex :& (st :& es))
-> Stream [Char] (ex :& (st :& es))
-> Counter4 (ex :& (st :& es))
forall (e :: Effects).
State Int e -> Exception () e -> Stream [Char] e -> Counter4 e
MkCounter4 (State Int st -> State Int (ex :& (st :& es))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
State Int e -> State Int es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle State Int st
st) (Exception () ex -> Exception () (ex :& (st :& es))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Exception () e -> Exception () es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle Exception () ex
ex) (Stream [Char] e1 -> Stream [Char] (ex :& (st :& es))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Coroutine [Char] () e -> Coroutine [Char] () es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle Stream [Char] e1
y))
    State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st

exampleCounter4 :: ([String], Int)
exampleCounter4 :: ([[Char]], Int)
exampleCounter4 = (forall (es :: Effects). Eff es ([[Char]], Int)) -> ([[Char]], Int)
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ([[Char]], Int))
 -> ([[Char]], Int))
-> (forall (es :: Effects). Eff es ([[Char]], Int))
-> ([[Char]], Int)
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
-> Eff es ([[Char]], Int)
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList ((forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
 -> Eff es ([[Char]], Int))
-> (forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
-> Eff es ([[Char]], Int)
forall a b. (a -> b) -> a -> b
$ \Stream [Char] e1
y -> do
  Stream [Char] e1
-> (forall {e :: Effects}. Counter4 e -> Eff (e :& (e1 :& es)) ())
-> Eff (e1 :& es) Int
forall (e1 :: Effects) (es :: Effects) r.
(e1 :> es) =>
Stream [Char] e1
-> (forall (e :: Effects). Counter4 e -> Eff (e :& es) r)
-> Eff es Int
runCounter4 Stream [Char] e1
y ((forall {e :: Effects}. Counter4 e -> Eff (e :& (e1 :& es)) ())
 -> Eff (e1 :& es) Int)
-> (forall {e :: Effects}. Counter4 e -> Eff (e :& (e1 :& es)) ())
-> Eff (e1 :& es) Int
forall a b. (a -> b) -> a -> b
$ \Counter4 e
c -> do
    Counter4 e -> Eff (e :& (e1 :& es)) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter4 e -> Eff es ()
incCounter4 Counter4 e
c
    Counter4 e -> Eff (e :& (e1 :& es)) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter4 e -> Eff es ()
incCounter4 Counter4 e
c
    Int
n <- Counter4 e -> [Char] -> Eff (e :& (e1 :& es)) Int
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter4 e -> [Char] -> Eff es Int
getCounter4 Counter4 e
c [Char]
"I'm getting the counter"
    Bool -> Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2) (Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ())
-> Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ()
forall a b. (a -> b) -> a -> b
$
      Stream [Char] e1 -> [Char] -> Eff (e :& (e1 :& es)) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e1
y [Char]
"n was 2, as expected"

-- > exampleCounter4
-- (["Count was even","I'm getting the counter","n was 2, as expected"],2)

-- Counter 5

data Counter5 e = MkCounter5
  { forall (e :: Effects). Counter5 e -> Eff e ()
incCounter5Impl :: Eff e (),
    forall (e :: Effects). Counter5 e -> [Char] -> Eff e Int
getCounter5Impl :: String -> Eff e Int
  }

incCounter5 :: (e :> es) => Counter5 e -> Eff es ()
incCounter5 :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter5 e -> Eff es ()
incCounter5 Counter5 e
e = Eff e () -> Eff es ()
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl (Counter5 e -> Eff e ()
forall (e :: Effects). Counter5 e -> Eff e ()
incCounter5Impl Counter5 e
e)

getCounter5 :: (e :> es) => Counter5 e -> String -> Eff es Int
getCounter5 :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter5 e -> [Char] -> Eff es Int
getCounter5 Counter5 e
e [Char]
msg = Eff e Int -> Eff es Int
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl (Counter5 e -> [Char] -> Eff e Int
forall (e :: Effects). Counter5 e -> [Char] -> Eff e Int
getCounter5Impl Counter5 e
e [Char]
msg)

runCounter5 ::
  (e1 :> es) =>
  Stream String e1 ->
  (forall e. Counter5 e -> Eff (e :& es) r) ->
  Eff es Int
runCounter5 :: forall (e1 :: Effects) (es :: Effects) r.
(e1 :> es) =>
Stream [Char] e1
-> (forall (e :: Effects). Counter5 e -> Eff (e :& es) r)
-> Eff es Int
runCounter5 Stream [Char] e1
y forall (e :: Effects). Counter5 e -> Eff (e :& es) r
k =
  Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
0 ((forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
 -> Eff es Int)
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
    Either () r
_ <- (forall (ex :: Effects).
 Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception () ex -> Eff (ex :& (st :& es)) r)
 -> Eff (st :& es) (Either () r))
-> (forall (ex :: Effects).
    Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall a b. (a -> b) -> a -> b
$ \Exception () ex
ex -> do
      (Counter5 (ex :& (st :& es)) -> Eff ((ex :& (st :& es)) :& es) r)
-> Counter5 (ex :& (st :& es)) -> Eff (ex :& (st :& es)) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn
        Counter5 (ex :& (st :& es)) -> Eff ((ex :& (st :& es)) :& es) r
forall (e :: Effects). Counter5 e -> Eff (e :& es) r
k
        ( MkCounter5
            { incCounter5Impl :: Eff (ex :& (st :& es)) ()
incCounter5Impl = do
                Int
count <- State Int st -> Eff (ex :& (st :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st

                Bool -> Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int -> Bool
forall a. Integral a => a -> Bool
even Int
count) (Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ())
-> Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ()
forall a b. (a -> b) -> a -> b
$
                  Stream [Char] e1 -> [Char] -> Eff (ex :& (st :& es)) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e1
y [Char]
"Count was even"

                Bool -> Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10) (Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ())
-> Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ()
forall a b. (a -> b) -> a -> b
$
                  Exception () ex -> () -> Eff (ex :& (st :& es)) ()
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception () ex
ex ()

                State Int st -> Int -> Eff (ex :& (st :& es)) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int st
st (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1),
              getCounter5Impl :: [Char] -> Eff (ex :& (st :& es)) Int
getCounter5Impl = \[Char]
msg -> do
                Stream [Char] e1 -> [Char] -> Eff (ex :& (st :& es)) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e1
y [Char]
msg
                State Int st -> Eff (ex :& (st :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st
            }
        )
    State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st

exampleCounter5 :: ([String], Int)
exampleCounter5 :: ([[Char]], Int)
exampleCounter5 = (forall (es :: Effects). Eff es ([[Char]], Int)) -> ([[Char]], Int)
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ([[Char]], Int))
 -> ([[Char]], Int))
-> (forall (es :: Effects). Eff es ([[Char]], Int))
-> ([[Char]], Int)
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
-> Eff es ([[Char]], Int)
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList ((forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
 -> Eff es ([[Char]], Int))
-> (forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
-> Eff es ([[Char]], Int)
forall a b. (a -> b) -> a -> b
$ \Stream [Char] e1
y -> do
  Stream [Char] e1
-> (forall {e :: Effects}. Counter5 e -> Eff (e :& (e1 :& es)) ())
-> Eff (e1 :& es) Int
forall (e1 :: Effects) (es :: Effects) r.
(e1 :> es) =>
Stream [Char] e1
-> (forall (e :: Effects). Counter5 e -> Eff (e :& es) r)
-> Eff es Int
runCounter5 Stream [Char] e1
y ((forall {e :: Effects}. Counter5 e -> Eff (e :& (e1 :& es)) ())
 -> Eff (e1 :& es) Int)
-> (forall {e :: Effects}. Counter5 e -> Eff (e :& (e1 :& es)) ())
-> Eff (e1 :& es) Int
forall a b. (a -> b) -> a -> b
$ \Counter5 e
c -> do
    Counter5 e -> Eff (e :& (e1 :& es)) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter5 e -> Eff es ()
incCounter5 Counter5 e
c
    Counter5 e -> Eff (e :& (e1 :& es)) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter5 e -> Eff es ()
incCounter5 Counter5 e
c
    Int
n <- Counter5 e -> [Char] -> Eff (e :& (e1 :& es)) Int
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter5 e -> [Char] -> Eff es Int
getCounter5 Counter5 e
c [Char]
"I'm getting the counter"
    Bool -> Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2) (Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ())
-> Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ()
forall a b. (a -> b) -> a -> b
$
      Stream [Char] e1 -> [Char] -> Eff (e :& (e1 :& es)) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e1
y [Char]
"n was 2, as expected"

-- > exampleCounter5
-- (["Count was even","I'm getting the counter","n was 2, as expected"],2)

-- Counter 6

data Counter6 e = MkCounter6
  { forall (e :: Effects). Counter6 e -> Eff e ()
incCounter6Impl :: Eff e (),
    forall (e :: Effects). Counter6 e -> State Int e
counter6State :: State Int e,
    forall (e :: Effects). Counter6 e -> Stream [Char] e
counter6Stream :: Stream String e
  }

incCounter6 :: (e :> es) => Counter6 e -> Eff es ()
incCounter6 :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter6 e -> Eff es ()
incCounter6 Counter6 e
e = Eff e () -> Eff es ()
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl (Counter6 e -> Eff e ()
forall (e :: Effects). Counter6 e -> Eff e ()
incCounter6Impl Counter6 e
e)

getCounter6 :: (e :> es) => Counter6 e -> String -> Eff es Int
getCounter6 :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter6 e -> [Char] -> Eff es Int
getCounter6 (MkCounter6 Eff e ()
_ State Int e
st Stream [Char] e
y) [Char]
msg = do
  Stream [Char] e -> [Char] -> Eff es ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e
y [Char]
msg
  State Int e -> Eff es Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int e
st

runCounter6 ::
  (e1 :> es) =>
  Stream String e1 ->
  (forall e. Counter6 e -> Eff (e :& es) r) ->
  Eff es Int
runCounter6 :: forall (e1 :: Effects) (es :: Effects) r.
(e1 :> es) =>
Stream [Char] e1
-> (forall (e :: Effects). Counter6 e -> Eff (e :& es) r)
-> Eff es Int
runCounter6 Stream [Char] e1
y forall (e :: Effects). Counter6 e -> Eff (e :& es) r
k =
  Int
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState Int
0 ((forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
 -> Eff es Int)
-> (forall {st :: Effects}. State Int st -> Eff (st :& es) Int)
-> Eff es Int
forall a b. (a -> b) -> a -> b
$ \State Int st
st -> do
    Either () r
_ <- (forall (ex :: Effects).
 Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception () ex -> Eff (ex :& (st :& es)) r)
 -> Eff (st :& es) (Either () r))
-> (forall (ex :: Effects).
    Exception () ex -> Eff (ex :& (st :& es)) r)
-> Eff (st :& es) (Either () r)
forall a b. (a -> b) -> a -> b
$ \Exception () ex
ex -> do
      (Counter6 (ex :& (st :& es)) -> Eff ((ex :& (st :& es)) :& es) r)
-> Counter6 (ex :& (st :& es)) -> Eff (ex :& (st :& es)) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn
        Counter6 (ex :& (st :& es)) -> Eff ((ex :& (st :& es)) :& es) r
forall (e :: Effects). Counter6 e -> Eff (e :& es) r
k
        ( MkCounter6
            { incCounter6Impl :: Eff (ex :& (st :& es)) ()
incCounter6Impl = do
                Int
count <- State Int st -> Eff (ex :& (st :& es)) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st

                Bool -> Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int -> Bool
forall a. Integral a => a -> Bool
even Int
count) (Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ())
-> Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ()
forall a b. (a -> b) -> a -> b
$
                  Stream [Char] e1 -> [Char] -> Eff (ex :& (st :& es)) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e1
y [Char]
"Count was even"

                Bool -> Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
10) (Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ())
-> Eff (ex :& (st :& es)) () -> Eff (ex :& (st :& es)) ()
forall a b. (a -> b) -> a -> b
$
                  Exception () ex -> () -> Eff (ex :& (st :& es)) ()
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception () ex
ex ()

                State Int st -> Int -> Eff (ex :& (st :& es)) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> s -> Eff es ()
put State Int st
st (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1),
              counter6State :: State Int (ex :& (st :& es))
counter6State = State Int st -> State Int (ex :& (st :& es))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
State Int e -> State Int es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle State Int st
st,
              counter6Stream :: Stream [Char] (ex :& (st :& es))
counter6Stream = Stream [Char] e1 -> Stream [Char] (ex :& (st :& es))
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Coroutine [Char] () e -> Coroutine [Char] () es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle Stream [Char] e1
y
            }
        )
    State Int st -> Eff (st :& es) Int
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State Int st
st

exampleCounter6 :: ([String], Int)
exampleCounter6 :: ([[Char]], Int)
exampleCounter6 = (forall (es :: Effects). Eff es ([[Char]], Int)) -> ([[Char]], Int)
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es ([[Char]], Int))
 -> ([[Char]], Int))
-> (forall (es :: Effects). Eff es ([[Char]], Int))
-> ([[Char]], Int)
forall a b. (a -> b) -> a -> b
$ (forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
-> Eff es ([[Char]], Int)
forall a (es :: Effects) r.
(forall (e1 :: Effects). Stream a e1 -> Eff (e1 :& es) r)
-> Eff es ([a], r)
yieldToList ((forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
 -> Eff es ([[Char]], Int))
-> (forall (e1 :: Effects). Stream [Char] e1 -> Eff (e1 :& es) Int)
-> Eff es ([[Char]], Int)
forall a b. (a -> b) -> a -> b
$ \Stream [Char] e1
y -> do
  Stream [Char] e1
-> (forall {e :: Effects}. Counter6 e -> Eff (e :& (e1 :& es)) ())
-> Eff (e1 :& es) Int
forall (e1 :: Effects) (es :: Effects) r.
(e1 :> es) =>
Stream [Char] e1
-> (forall (e :: Effects). Counter6 e -> Eff (e :& es) r)
-> Eff es Int
runCounter6 Stream [Char] e1
y ((forall {e :: Effects}. Counter6 e -> Eff (e :& (e1 :& es)) ())
 -> Eff (e1 :& es) Int)
-> (forall {e :: Effects}. Counter6 e -> Eff (e :& (e1 :& es)) ())
-> Eff (e1 :& es) Int
forall a b. (a -> b) -> a -> b
$ \Counter6 e
c -> do
    Counter6 e -> Eff (e :& (e1 :& es)) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter6 e -> Eff es ()
incCounter6 Counter6 e
c
    Counter6 e -> Eff (e :& (e1 :& es)) ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter6 e -> Eff es ()
incCounter6 Counter6 e
c
    Int
n <- Counter6 e -> [Char] -> Eff (e :& (e1 :& es)) Int
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Counter6 e -> [Char] -> Eff es Int
getCounter6 Counter6 e
c [Char]
"I'm getting the counter"
    Bool -> Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2) (Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ())
-> Eff (e :& (e1 :& es)) () -> Eff (e :& (e1 :& es)) ()
forall a b. (a -> b) -> a -> b
$
      Stream [Char] e1 -> [Char] -> Eff (e :& (e1 :& es)) ()
forall (e1 :: Effects) (es :: Effects) a.
(e1 :> es) =>
Stream a e1 -> a -> Eff es ()
yield Stream [Char] e1
y [Char]
"n was 2, as expected"

-- > exampleCounter6
-- (["Count was even","I'm getting the counter","n was 2, as expected"],2)

-- FileSystem

data FileSystem es = MkFileSystem
  { forall (es :: Effects). FileSystem es -> [Char] -> Eff es [Char]
readFileImpl :: FilePath -> Eff es String,
    forall (es :: Effects).
FileSystem es -> [Char] -> [Char] -> Eff es ()
writeFileImpl :: FilePath -> String -> Eff es ()
  }

readFile :: (e :> es) => FileSystem e -> FilePath -> Eff es String
readFile :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
FileSystem e -> [Char] -> Eff es [Char]
readFile FileSystem e
fs [Char]
filepath = Eff e [Char] -> Eff es [Char]
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl (FileSystem e -> [Char] -> Eff e [Char]
forall (es :: Effects). FileSystem es -> [Char] -> Eff es [Char]
readFileImpl FileSystem e
fs [Char]
filepath)

writeFile :: (e :> es) => FileSystem e -> FilePath -> String -> Eff es ()
writeFile :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
FileSystem e -> [Char] -> [Char] -> Eff es ()
writeFile FileSystem e
fs [Char]
filepath [Char]
contents = Eff e () -> Eff es ()
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl (FileSystem e -> [Char] -> [Char] -> Eff e ()
forall (es :: Effects).
FileSystem es -> [Char] -> [Char] -> Eff es ()
writeFileImpl FileSystem e
fs [Char]
filepath [Char]
contents)

runFileSystemPure ::
  (e1 :> es) =>
  Exception String e1 ->
  [(FilePath, String)] ->
  (forall e2. FileSystem e2 -> Eff (e2 :& es) r) ->
  Eff es r
runFileSystemPure :: forall (e1 :: Effects) (es :: Effects) r.
(e1 :> es) =>
Exception [Char] e1
-> [([Char], [Char])]
-> (forall (e2 :: Effects). FileSystem e2 -> Eff (e2 :& es) r)
-> Eff es r
runFileSystemPure Exception [Char] e1
ex [([Char], [Char])]
fs0 forall (e2 :: Effects). FileSystem e2 -> Eff (e2 :& es) r
k =
  [([Char], [Char])]
-> (forall {st :: Effects}.
    State [([Char], [Char])] st -> Eff (st :& es) r)
-> Eff es r
forall s (es :: Effects) a.
s
-> (forall (st :: Effects). State s st -> Eff (st :& es) a)
-> Eff es a
evalState [([Char], [Char])]
fs0 ((forall {st :: Effects}.
  State [([Char], [Char])] st -> Eff (st :& es) r)
 -> Eff es r)
-> (forall {st :: Effects}.
    State [([Char], [Char])] st -> Eff (st :& es) r)
-> Eff es r
forall a b. (a -> b) -> a -> b
$ \State [([Char], [Char])] st
fs ->
    (FileSystem (st :& es) -> Eff ((st :& es) :& es) r)
-> FileSystem (st :& es) -> Eff (st :& es) r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn
      FileSystem (st :& es) -> Eff ((st :& es) :& es) r
forall (e2 :: Effects). FileSystem e2 -> Eff (e2 :& es) r
k
      MkFileSystem
        { readFileImpl :: [Char] -> Eff (st :& es) [Char]
readFileImpl = \[Char]
path -> do
            [([Char], [Char])]
fs' <- State [([Char], [Char])] st -> Eff (st :& es) [([Char], [Char])]
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> Eff es s
get State [([Char], [Char])] st
fs
            case [Char] -> [([Char], [Char])] -> Maybe [Char]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup [Char]
path [([Char], [Char])]
fs' of
              Maybe [Char]
Nothing ->
                Exception [Char] e1 -> [Char] -> Eff (st :& es) [Char]
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception [Char] e1
ex ([Char]
"File not found: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
path)
              Just [Char]
s -> [Char] -> Eff (st :& es) [Char]
forall a. a -> Eff (st :& es) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Char]
s,
          writeFileImpl :: [Char] -> [Char] -> Eff (st :& es) ()
writeFileImpl = \[Char]
path [Char]
contents ->
            State [([Char], [Char])] st
-> ([([Char], [Char])] -> [([Char], [Char])]) -> Eff (st :& es) ()
forall (st :: Effects) (es :: Effects) s.
(st :> es) =>
State s st -> (s -> s) -> Eff es ()
modify State [([Char], [Char])] st
fs (([Char]
path, [Char]
contents) :)
        }

runFileSystemIO ::
  forall e1 e2 es r.
  (e1 :> es, e2 :> es) =>
  Exception String e1 ->
  IOE e2 ->
  (forall e. FileSystem e -> Eff (e :& es) r) ->
  Eff es r
runFileSystemIO :: forall (e1 :: Effects) (e2 :: Effects) (es :: Effects) r.
(e1 :> es, e2 :> es) =>
Exception [Char] e1
-> IOE e2
-> (forall (e :: Effects). FileSystem e -> Eff (e :& es) r)
-> Eff es r
runFileSystemIO Exception [Char] e1
ex IOE e2
io forall (e :: Effects). FileSystem e -> Eff (e :& es) r
k =
  (FileSystem es -> Eff (es :& es) r) -> FileSystem es -> Eff es r
forall (e :: Effects) (es :: Effects) t r.
(e :> es) =>
(t -> Eff (es :& e) r) -> t -> Eff es r
useImplIn
    FileSystem es -> Eff (es :& es) r
forall (e :: Effects). FileSystem e -> Eff (e :& es) r
k
    MkFileSystem
      { readFileImpl :: [Char] -> Eff es [Char]
readFileImpl =
          IO [Char] -> Eff es [Char]
forall (ess :: Effects) a.
(e1 :> ess, e2 :> ess) =>
IO a -> Eff ess a
adapt (IO [Char] -> Eff es [Char])
-> ([Char] -> IO [Char]) -> [Char] -> Eff es [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> IO [Char]
Prelude.readFile,
        writeFileImpl :: [Char] -> [Char] -> Eff es ()
writeFileImpl =
          \[Char]
path -> IO () -> Eff es ()
forall (ess :: Effects) a.
(e1 :> ess, e2 :> ess) =>
IO a -> Eff ess a
adapt (IO () -> Eff es ()) -> ([Char] -> IO ()) -> [Char] -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> [Char] -> IO ()
Prelude.writeFile [Char]
path
      }
  where
    adapt :: (e1 :> ess, e2 :> ess) => IO a -> Eff ess a
    adapt :: forall (ess :: Effects) a.
(e1 :> ess, e2 :> ess) =>
IO a -> Eff ess a
adapt IO a
m =
      IOE e2
-> IO (Either IOException a) -> Eff ess (Either IOException a)
forall (e :: Effects) (es :: Effects) a.
(e :> es) =>
IOE e -> IO a -> Eff es a
effIO IOE e2
io (forall e a. Exception e => IO a -> IO (Either e a)
Control.Exception.try @IOException IO a
m) Eff ess (Either IOException a)
-> (Either IOException a -> Eff ess a) -> Eff ess a
forall a b. Eff ess a -> (a -> Eff ess b) -> Eff ess b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Left IOException
e -> Exception [Char] e1 -> [Char] -> Eff ess a
forall (ex :: Effects) (es :: Effects) e a.
(ex :> es) =>
Exception e ex -> e -> Eff es a
throw Exception [Char] e1
ex (IOException -> [Char]
forall a. Show a => a -> [Char]
show IOException
e)
        Right a
r -> a -> Eff ess a
forall a. a -> Eff ess a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
r

action :: (e :> es) => FileSystem e -> Eff es String
action :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
FileSystem e -> Eff es [Char]
action FileSystem e
fs = do
  [Char]
file <- FileSystem e -> [Char] -> Eff es [Char]
forall (e :: Effects) (es :: Effects).
(e :> es) =>
FileSystem e -> [Char] -> Eff es [Char]
readFile FileSystem e
fs [Char]
"/dev/null"
  Bool -> Eff es () -> Eff es ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Char]
file Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (Eff es () -> Eff es ()) -> Eff es () -> Eff es ()
forall a b. (a -> b) -> a -> b
$ do
    FileSystem e -> [Char] -> [Char] -> Eff es ()
forall (e :: Effects) (es :: Effects).
(e :> es) =>
FileSystem e -> [Char] -> [Char] -> Eff es ()
writeFile FileSystem e
fs [Char]
"/tmp/bluefin" [Char]
"Hello!\n"
  FileSystem e -> [Char] -> Eff es [Char]
forall (e :: Effects) (es :: Effects).
(e :> es) =>
FileSystem e -> [Char] -> Eff es [Char]
readFile FileSystem e
fs [Char]
"/tmp/doesn't exist"

exampleRunFileSystemPure :: Either String String
exampleRunFileSystemPure :: Either [Char] [Char]
exampleRunFileSystemPure = (forall (es :: Effects). Eff es (Either [Char] [Char]))
-> Either [Char] [Char]
forall a. (forall (es :: Effects). Eff es a) -> a
runPureEff ((forall (es :: Effects). Eff es (Either [Char] [Char]))
 -> Either [Char] [Char])
-> (forall (es :: Effects). Eff es (Either [Char] [Char]))
-> Either [Char] [Char]
forall a b. (a -> b) -> a -> b
$ (forall (ex :: Effects).
 Exception [Char] ex -> Eff (ex :& es) [Char])
-> Eff es (Either [Char] [Char])
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception [Char] ex -> Eff (ex :& es) [Char])
 -> Eff es (Either [Char] [Char]))
-> (forall (ex :: Effects).
    Exception [Char] ex -> Eff (ex :& es) [Char])
-> Eff es (Either [Char] [Char])
forall a b. (a -> b) -> a -> b
$ \Exception [Char] ex
ex ->
  Exception [Char] ex
-> [([Char], [Char])]
-> (forall (e2 :: Effects).
    FileSystem e2 -> Eff (e2 :& (ex :& es)) [Char])
-> Eff (ex :& es) [Char]
forall (e1 :: Effects) (es :: Effects) r.
(e1 :> es) =>
Exception [Char] e1
-> [([Char], [Char])]
-> (forall (e2 :: Effects). FileSystem e2 -> Eff (e2 :& es) r)
-> Eff es r
runFileSystemPure Exception [Char] ex
ex [([Char]
"/dev/null", [Char]
"")] FileSystem e2 -> Eff (e2 :& (ex :& es)) [Char]
forall (e2 :: Effects).
FileSystem e2 -> Eff (e2 :& (ex :& es)) [Char]
forall (e :: Effects) (es :: Effects).
(e :> es) =>
FileSystem e -> Eff es [Char]
action

-- > exampleRunFileSystemPure
-- Left "File not found: /tmp/doesn't exist"

exampleRunFileSystemIO :: IO (Either String String)
exampleRunFileSystemIO :: IO (Either [Char] [Char])
exampleRunFileSystemIO = (forall (e :: Effects) (es :: Effects).
 IOE e -> Eff (e :& es) (Either [Char] [Char]))
-> IO (Either [Char] [Char])
forall a.
(forall (e :: Effects) (es :: Effects). IOE e -> Eff (e :& es) a)
-> IO a
runEff ((forall (e :: Effects) (es :: Effects).
  IOE e -> Eff (e :& es) (Either [Char] [Char]))
 -> IO (Either [Char] [Char]))
-> (forall (e :: Effects) (es :: Effects).
    IOE e -> Eff (e :& es) (Either [Char] [Char]))
-> IO (Either [Char] [Char])
forall a b. (a -> b) -> a -> b
$ \IOE e
io -> (forall (ex :: Effects).
 Exception [Char] ex -> Eff (ex :& (e :& es)) [Char])
-> Eff (e :& es) (Either [Char] [Char])
forall e (es :: Effects) a.
(forall (ex :: Effects). Exception e ex -> Eff (ex :& es) a)
-> Eff es (Either e a)
try ((forall (ex :: Effects).
  Exception [Char] ex -> Eff (ex :& (e :& es)) [Char])
 -> Eff (e :& es) (Either [Char] [Char]))
-> (forall (ex :: Effects).
    Exception [Char] ex -> Eff (ex :& (e :& es)) [Char])
-> Eff (e :& es) (Either [Char] [Char])
forall a b. (a -> b) -> a -> b
$ \Exception [Char] ex
ex ->
  Exception [Char] ex
-> IOE e
-> (forall (e :: Effects).
    FileSystem e -> Eff (e :& (ex :& (e :& es))) [Char])
-> Eff (ex :& (e :& es)) [Char]
forall (e1 :: Effects) (e2 :: Effects) (es :: Effects) r.
(e1 :> es, e2 :> es) =>
Exception [Char] e1
-> IOE e2
-> (forall (e :: Effects). FileSystem e -> Eff (e :& es) r)
-> Eff es r
runFileSystemIO Exception [Char] ex
ex IOE e
io FileSystem e -> Eff (e :& (ex :& (e :& es))) [Char]
forall (e :: Effects).
FileSystem e -> Eff (e :& (ex :& (e :& es))) [Char]
forall (e :: Effects) (es :: Effects).
(e :> es) =>
FileSystem e -> Eff es [Char]
action

-- > exampleRunFileSystemIO
-- Left "/tmp/doesn't exist: openFile: does not exist (No such file or directory)"
-- \$ cat /tmp/bluefin
-- Hello!

-- instance Handle example

data Application e = MkApplication
  { forall (e :: Effects).
Application e -> [Char] -> Int -> Eff e [[Char]]
queryDatabase :: String -> Int -> Eff e [String],
    forall (e :: Effects). Application e -> State (Int, Bool) e
applicationState :: State (Int, Bool) e,
    forall (e :: Effects). Application e -> Stream [Char] e
logger :: Stream String e
  }

instance Handle Application where
  mapHandle :: forall (e :: Effects) (es :: Effects).
(e :> es) =>
Application e -> Application es
mapHandle
    MkApplication
      { queryDatabase :: forall (e :: Effects).
Application e -> [Char] -> Int -> Eff e [[Char]]
queryDatabase = [Char] -> Int -> Eff e [[Char]]
q,
        applicationState :: forall (e :: Effects). Application e -> State (Int, Bool) e
applicationState = State (Int, Bool) e
a,
        logger :: forall (e :: Effects). Application e -> Stream [Char] e
logger = Stream [Char] e
l
      } =
      MkApplication
        { queryDatabase :: [Char] -> Int -> Eff es [[Char]]
queryDatabase = (((Int -> Eff e [[Char]]) -> Int -> Eff es [[Char]])
-> ([Char] -> Int -> Eff e [[Char]])
-> [Char]
-> Int
-> Eff es [[Char]]
forall a b. (a -> b) -> ([Char] -> a) -> [Char] -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Int -> Eff e [[Char]]) -> Int -> Eff es [[Char]])
 -> ([Char] -> Int -> Eff e [[Char]])
 -> [Char]
 -> Int
 -> Eff es [[Char]])
-> ((Eff e [[Char]] -> Eff es [[Char]])
    -> (Int -> Eff e [[Char]]) -> Int -> Eff es [[Char]])
-> (Eff e [[Char]] -> Eff es [[Char]])
-> ([Char] -> Int -> Eff e [[Char]])
-> [Char]
-> Int
-> Eff es [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Eff e [[Char]] -> Eff es [[Char]])
-> (Int -> Eff e [[Char]]) -> Int -> Eff es [[Char]]
forall a b. (a -> b) -> (Int -> a) -> Int -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) Eff e [[Char]] -> Eff es [[Char]]
forall (e :: Effects) (es :: Effects) r.
(e :> es) =>
Eff e r -> Eff es r
useImpl [Char] -> Int -> Eff e [[Char]]
q,
          applicationState :: State (Int, Bool) es
applicationState = State (Int, Bool) e -> State (Int, Bool) es
forall (e :: Effects) (es :: Effects).
(e :> es) =>
State (Int, Bool) e -> State (Int, Bool) es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle State (Int, Bool) e
a,
          logger :: Stream [Char] es
logger = Stream [Char] e -> Stream [Char] es
forall (e :: Effects) (es :: Effects).
(e :> es) =>
Coroutine [Char] () e -> Coroutine [Char] () es
forall (h :: Effects -> *) (e :: Effects) (es :: Effects).
(Handle h, e :> es) =>
h e -> h es
mapHandle Stream [Char] e
l
        }