Bladeren bron

Hello, Monads!

Lucas Stadler 13 jaren geleden
bovenliggende
commit
92c7760f23
1 gewijzigde bestanden met toevoegingen van 53 en 0 verwijderingen
  1. 53 0
      hs/HelloMonads.hs

+ 53 - 0
hs/HelloMonads.hs

@ -0,0 +1,53 @@
1
import Prelude hiding (Maybe(..), print, putStr, putStrLn, getLine, getContent)
2
3
-- define Maybe here so we can implement our own monad
4
data Maybe a = Just a | Nothing deriving (Show, Eq, Ord)
5
6
instance Monad Maybe where
7
    (Just x) >>= action = action x
8
    Nothing  >>= action = Nothing
9
10
    -- apparently optional:
11
    -- maybeA   >>  maybeB = maybeA >>= \_ -> maybeB
12
13
    return x            = Just x
14
15
    -- FIXME: fail?
16
    -- fail _ = Nothing
17
18
maybeAdd m1 m2 = m1 >>= \x -> m2 >>= \y -> return (x + y)
19
20
maybeAdd' m1 m2 = do
21
    x <- m1
22
    y <- m2
23
    return $ x + y
24
25
type InputState = String
26
type OutputState = String
27
data WeirdIO a = WeirdIO ((InputState, OutputState) -> ((InputState, OutputState), a))
28
29
executeWeirdIO :: InputState -> WeirdIO a -> ((InputState, OutputState), a)
30
executeWeirdIO input (WeirdIO f) = {-snd . fst $-} f (input, "")
31
32
instance Monad WeirdIO where
33
    (WeirdIO changeState) >>= action = WeirdIO $ \state ->
34
        let ((i, o), x) = changeState state
35
            (WeirdIO f) = action x
36
        in f ((i, o))
37
38
    return x = WeirdIO $ \state -> (state, x)
39
40
takeUntil :: (a -> Bool) -> [a] -> [a]
41
takeUntil p [] = []
42
takeUntil p (x:xs) = if (p x) then [x] else x : takeUntil p xs
43
44
dropUntil p [] = []
45
dropUntil p (x:xs) = if (p x) then xs else dropUntil p xs
46
47
print x = WeirdIO $ \(i, o) -> ((i, o ++ show x ++ "\n"), ())
48
putStr s = WeirdIO $ \(i, o) -> ((i, o ++ s), ())
49
putStrLn s = putStr $ s ++ "\n"
50
51
getChar = WeirdIO $ \(c:cs, o) -> ((cs, o), c)
52
getLine = WeirdIO $ \(i, o) -> (((dropUntil (== '\n') i), o), takeWhile (/= '\n') i)
53
getContent = WeirdIO $ \(i, o) -> (("", o), i)