-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmonadic-functions.hs
81 lines (63 loc) · 2.24 KB
/
monadic-functions.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import Control.Applicative
import Control.Monad
import Control.Monad.Writer
-- liftM is for Monads what fmap is for Functors
a1 = liftM (*3) (Just 8)
a2 = fmap (*3) (Just 8)
a3 = runWriter $ liftM not $ writer (True, "chickpeas")
a4 = runWriter $ fmap not $ writer (True, "chickpeas")
--a5 = runState (liftM (+100) pop) [1,2,3,4]
--a6 = runState (fmap (+100) pop) [1,2,3,4]
-- definition of liftM
-- liftM :: (Monad m) => (a -> b) -> m a -> m b
-- liftM f m = m >>= (\x -> return (f x))
-- ap is the same as <*> with Monad class constraint instead of Applicative
-- ap :: (Monad m) => m (a -> b) -> m a -> m b
-- ap mf m = do
-- f <- mf
-- x <- m
-- return (f x)
-- examples of ap
b1 = Just (+3) <*> Just 4
b2 = Just (+3) `ap` Just 4
b3 = [(+1),(+2),(+3)] <*> [10,11]
b4 = [(+1),(+2),(+3)] `ap` [10,11]
-- the join funcion (flatten in Scala)
-- join :: (Monad m) => m (m a) -> m a
-- m >>= f is always the same thing as join (fmap f m)
c1 = join (Just (Just 9))
c2 = join (Just Nothing)
c3 = join Nothing
-- for lists join is the same as concat
c4 = join [[1,2,3],[4,5,6]]
-- for writer is using the mappend from the Monoid class constraint
c5 = runWriter $ join (writer (writer (1,"aaa"),"bbb"))
-- flattening Either
c6 = join (Right (Right 9)) :: Either String Int
c7 = join (Right (Left "error")) :: Either String Int
c8 = join (Left "error") :: Either String Int
-- for state monad
-- c9 = runState (join (State $ \s -> (push 10,1:2:s))) [0,0,0]
-- result: ((),[10,1,2,0,0,0])
-- filter function
keepSmall :: Int -> Writer [String] Bool
keepSmall x
| x < 4 = do
tell ["Keeping " ++ show x]
return True
| otherwise = do
tell [show x ++ " is too large, throwing it away"]
return False
e1 = fst $ runWriter $ filterM keepSmall [9,1,5,2,10,3]
e2 = mapM_ putStrLn $ snd $ runWriter $ filterM keepSmall [9,1,5,2,10,3]
powerset :: [a] -> [[a]]
powerset xs = filterM (\x -> [True, False]) xs
f1 = powerset [1,2,3]
-- foldM function
-- foldM :: (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
binSmalls :: Int -> Int -> Maybe Int
binSmalls acc x
| x > 9 = Nothing
| otherwise = Just (acc + x)
g1 = foldM binSmalls 0 [2,8,3,1]
g2 = foldM binSmalls 0 [2,11,3,1]