@@ -1,12 +1,16 @@
11module Main where
22
33import Prelude
4+import Control.Monad.Eff.Console
45
56data Tuple a b = Tuple a b
67
7−class MonadState s m where
8+instance showTuple :: (Show a, Show b) => Show (Tuple a b) where
9+ show (Tuple a b) = "(" <> show a <> ", " <> show b <> ")"
10+
11+class Monad m <= MonadState s m where
812 get :: m s
9− put :: s -> m {}
13+ put :: s -> m Unit
1014
1115data State s a = State (s -> Tuple s a)
1216
@@ -29,20 +33,29 @@ instance monadState :: Monad (State s)
2933
3034instance monadStateState :: MonadState s (State s) where
3135 get = State (\s -> Tuple s s)
32− put s = State (\_ -> Tuple s {})
33−
34−modify :: forall m s. (Prelude.Monad m, MonadState s m) => (s -> s) -> m {}
35−modify f = do
36− s <- get
37− put (f s)
38−
39−test :: Tuple String String
40−test = runState "" $ do
41− modify $ (++) "World!"
42− modify $ (++) "Hello, "
43− get
44−
45−main = do
46− let t1 = test
47− Control.Monad.Eff.Console.log "Done"
48−
36+ put s = State (\_ -> Tuple s unit)
37+
38+-- Without the call to same, the following strange (but correct, in the absence of
39+-- functional dependencies) type:
40+--
41+-- forall m t1 t2.
42+-- ( Bind m
43+-- , MonadState t1 m
44+-- , MonadState t2 m
45+-- ) => (t1 -> t2) -> m Unit
46+--
47+-- With the type hint, the inferred type is more sensible:
48+--
49+-- forall m t.
50+-- ( Bind m
51+-- , MonadState t m
52+-- ) => (t -> t) -> m Unit
53+modify f =
54+ do
55+ s <- get
56+ put (same f s)
57+ where
58+ same :: forall a. (a -> a) -> (a -> a)
59+ same = id
60+
61+main = print $ runState 0 (modify (+ 1))