@@ -0,0 +1,59 @@
1+module Kinds where
2+
3+-- Eff Monad
4+
5+foreign import data Eff :: # ! -> * -> *
6+
7+foreign import ret :: forall e a. a -> Eff e a
8+
9+foreign import (>>=) :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
10+
11+type Pure a = forall e. Eff e a
12+
13+foreign import runPure :: forall a. Pure a -> a
14+
15+-- Errors
16+
17+foreign import data Error :: * -> !
18+
19+foreign import throwError :: forall e r. e -> Eff (err :: Error e | r) {}
20+
21+foreign import catchError :: forall e r a. (e -> Eff r a) -> Eff (err :: Error e | r) a -> Eff r a
22+
23+-- State
24+
25+foreign import data State :: * -> !
26+
27+foreign import get :: forall s r. Eff (state :: State s | r) s
28+
29+foreign import set :: forall s r. s -> Eff (state :: State s | r) {}
30+
31+foreign import runState :: forall s r a. s -> Eff (state :: State s | r) a -> Eff r { value :: a, state :: s }
32+
33+-- ST
34+
35+foreign import data ST :: * -> !
36+
37+foreign import data STRef :: * -> * -> *
38+
39+foreign import newSTRef :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
40+
41+foreign import readSTRef :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
42+
43+foreign import modifySTRef :: forall a h r. (a -> a) -> STRef h a -> Eff (st :: ST h | r) {}
44+
45+foreign import runST :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
46+
47+-- Tests
48+
49+test1 = runPure (runState 0 (catchError (\s -> ret 0)
50+ (get >>= \s ->
51+ throwError "Error!" >>= \_ ->
52+ set (s + 1) >>= \_ ->
53+ ret s)))
54+
55+test2 = runPure (runST (
56+ newSTRef 0 >>= \ref ->
57+ modifySTRef (\n -> n + 1) ref >>= \_ ->
58+ readSTRef ref))
59+