Tonλ's blog May the λ be with you

PIH - ch10 - 3/3 - Declaring types and classes - exercises

by @ardumont on

Here is the last part of the chapter 10's exercises. Previous part:

Abstract Machine

Extend the abstract machine to support the use of multiplication.

The code adapted to deal with multiplication:

data Expr = Val Int | Add Expr Expr | Mult Expr Expr deriving Show

data Op = EVALM Expr | EVALA Expr | MUL Int | ADD Int deriving Show

type Cont = [Op]

eval :: Expr -> Cont -> Int
eval (Val n)    c = exec c n
eval (Mult x y) c = eval x (EVALM y : c)
eval (Add x y)  c = eval x (EVALA y : c)

exec :: Cont -> Int -> Int
exec []            n = n
exec (EVALM y : c) n = eval y (MUL n : c)
exec (EVALA y : c) n = eval y (ADD n : c)
exec (MUL m : c)   n = exec c (n * m)
exec (ADD m : c)   n = exec c (n + m)

val :: Expr -> Int
val e = eval e []

Output:

*AbstractMachine> val (Mult (Val 10) (Val 5))
50
*AbstractMachine> val (Add (Mult (Val 10) (Val 5)) (Val 100))
150

Instance

Complete the following instance declarations: = instance Monad Maybe where ··· instance Monad [] where ··· = In this context, [] denotes the list type [a] without its parameter.

Hint: First write down the types of return and >>= for each instance.

May(be)

data

The data May(be) definition:

data May a = Noth | Jus a

inject

To inject a value into the Maybe world, we wrap this value into a Jus and we're done:

return = Jus

bind

  • Noth binds to anything is Noth.
  • And if it is a value (Jus x)m then we can bind it to the monadic function f (f x).
Noth  >>= _ = Noth
(Jus x) >>= f = f x

complete

Complete definition:

data May a = Noth | Jus a

instance Monad May where
         return = Jus

         Noth  >>= _ = Noth
         (Jus x) >>= f = f x

[]

inject

To inject a value in the monadic world of list, just create a singleton list with this value:

-- return :: a -> [a]
return x = [x]

bind

To bind a list to the monadic function f, apply the monadic function f to the content of the list (so concatMap):

-- [a] -> (a -> [b]) -> [b]
l >>= f = concatMap f l

complete

instance Monad [] where
         return v = [v]

         -- m a -> (a -> m b) -> m b
         -- [a] -> (a -> [b]) -> [b]
         l >>= f = concatMap f l

Latest posts