Skip to content

Commit

Permalink
Monad typeclass. Maybe Monad. Do notation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabi Volpe committed Aug 22, 2016
1 parent d25e254 commit 01aec7b
Showing 1 changed file with 129 additions and 0 deletions.
129 changes: 129 additions & 0 deletions category-theory/monad.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
-- defining >>= for Maybe with a fancy name for now
applyMaybe :: Maybe a -> (a -> Maybe b) -> Maybe b
applyMaybe Nothing f = Nothing
applyMaybe (Just x) f = f x

a1 = Just 3 `applyMaybe` \x -> Just (x+1)
a2 = Just "smile" `applyMaybe` \x -> Just (x ++ " :)")
a3 = Nothing `applyMaybe` \x -> Just (x+1)
a4 = Nothing `applyMaybe` \x -> Just (x ++ " :)")
a5 = Just 3 `applyMaybe` \x -> if x > 2 then Just x else Nothing
a6 = Just 1 `applyMaybe` \x -> if x > 2 then Just x else Nothing

-- definition of Monad in Haskell (should have an Applicative class constraint but it doesn't...)
--class Monad m where
-- return :: a -> m a
--
-- (>>=) :: m a -> (a -> m b) -> m b
--
-- (>>) :: m a -> m b -> m b
-- x >> y = x >>= \_ -> y
--
-- fail :: String -> m a
-- fail msg = error msg

-- Monad instance for Maybe
--instance MyMonad Maybe where
-- return x = Just x
-- Nothing >>= f = Nothing
-- Just x >>= f = f x
-- fail _ = Nothing

-- examples on Maybe
b1 = return "WHAT" :: Maybe String
b2 = Just 9 >>= \x -> return (x*10)
b3 = Nothing >>= \x -> return (x*10)

-- interactive example
type Birds = Int
type Pole = (Birds,Birds)

landLeft1 :: Birds -> Pole -> Pole
landLeft1 n (left,right) = (left + n,right)

landRight1 :: Birds -> Pole -> Pole
landRight1 n (left,right) = (left,right + n)

-- try it out!
c1 = landLeft1 2 (0,0)
c2 = landRight1 1 (1,2)
c3 = landRight1 (-1) (1,2)
c4 = landLeft1 2 (landRight1 1 (landLeft1 1 (0,0)))

x -: f = f x

-- same as c4 using the function above
c5 = (0,0) -: landLeft1 1 -: landRight1 1 -: landLeft1 2

-- functions defined using Maybe
landLeft :: Birds -> Pole -> Maybe Pole
landLeft n (left,right)
| abs ((left + n) - right) < 4 = Just (left + n, right)
| otherwise = Nothing

landRight :: Birds -> Pole -> Maybe Pole
landRight n (left,right)
| abs (left - (right + n)) < 4 = Just (left, right + n)
| otherwise = Nothing

-- examples using these functions
d1 = landLeft 2 (0,0)
d2 = landLeft 10 (0,3)

-- using bind
e1 = landRight 1 (0,0) >>= landLeft 2
e2 = Nothing >>= landLeft 2
e3 = return (0,0) >>= landRight 2 >>= landLeft 2 >>= landRight 2

-- failing in the middle
e4 = return (0,0) >>= landLeft 1 >>= landRight 4 >>= landLeft (-1) >>= landRight (-2)

banana :: Pole -> Maybe Pole
banana _ = Nothing

e5 = return (0,0) >>= landLeft 1 >>= banana >>= landRight 1

-- using the function >> that ignores the input as banana does
e6 = return (0,0) >>= landLeft 1 >> Nothing >>= landRight 1

-- nested bind (>>=)
f1 = Just 3 >>= (\x -> Just "!" >>= (\y -> Just (show x ++ y)))

-- using do notation (for-comprehension in Scala)
foo :: Maybe String
foo = do
x <- Just 3
y <- Just "!"
Just (show x ++ y)

marySue :: Maybe Bool
marySue = do
x <- Just 9
Just (x > 8)

routine :: Maybe Pole
routine = do
start <- return (0,0)
first <- landLeft 2 start
second <- landRight 2 first
landLeft 1 second

ignored :: Maybe Pole
ignored = do
start <- return (0,0)
first <- landLeft 2 start
Nothing -- same to: _ <- Nothing
second <- landRight 2 first
landLeft 1 second

-- using pattern matching in monadic expressions
justH :: Maybe Char
justH = do
(x:xs) <- Just "hello"
return x

-- pattern matching that fails, invokes the fail monad function
wopwop :: Maybe Char
wopwop = do
(x:xs) <- Just ""
return x

0 comments on commit 01aec7b

Please sign in to comment.