Skip to content

Notes for Week 15 Monads Part 1

newmana edited this page Mar 25, 2012 · 26 revisions

Links:

Exercises:

Exercise 1

Given that we have Functors and Applicative Functors, what additional benefit do Monads give us?

Exercise 2

Monads are Applicative Functors. List all available methods on a Monadic instance.

Exercise 3

import qualified Data.Monoid as M

lessThanHundred :: Int -> Maybe Int 
lessThanHundred x = 

isEven :: Int -> Maybe Int
isEven x = 

complete :: Maybe String
complete =  (return "complete")

valid = 20 :: Int
invalid = 25 :: Int

withDo :: Int -> Maybe String
withDo value =

pipeline :: Int -> Maybe String
pipeline value =

testValidWithPipeline = pipeline valid == complete
testInvalidWithPipeline = pipeline invalid == Nothing
testValidWithDo = withDo valid == complete
testInvalidWithDo = withDo invalid == Nothing

testAll = (M.getAll $ M.mconcat $ map M.All [testValidWithPipeline, testInvalidWithPipeline, testValidWithDo, testInvalidWithDo]) == True

Given the above functions:

Write the implementations of the lessThanHundred, isEven, withDo and pipeline functions such that:

  1. Any value that is less than a hundred and is even should result in the pipeline function returning Just "complete".
  2. Any value that is either greater than a hundred or odd should result in the pipeline function returning Nothing.

The withDo function should use the "do" syntax and the pipeline method should use monadic functions. Essentially they return the same result but use different syntaxes.

Use the test* functions to verify your individual functions and the testAll function to verify all tests.

Questions raised during the group:

//TODO

Answers to Exercises:

Exercise 1

For a start, monads are functors and applicative functors. A monad is a monoid in a category of endo functions (functions that take and give the same type), with unit as the join as the binary operation.

"If we have a value with a context, m a, how do we apply to it a function that takes a normal a and returns a value with a context? In other words, how do we apply a function of type a -> m b to a value of type m a?"

Allows us to lift a function up into a computational context. Monads add bind function to applicative functions.

Exercise 2

return - takes something and wraps it in a monad. Same as pure.

= - bind takes a monadic value, to a function and returns a monadic value.

  • evaluate to unit or to the right hand value. fail - called when pattern matching fails.

Exercise 3

import Data.Char  
import Data.List
import Data.Monoid
import Data.Foldable
import qualified Data.Monoid as M

lessThanHundred :: Int -> Maybe Int 
lessThanHundred x = if (x < 100) then Just x else Nothing

isEven :: Int -> Maybe Int
isEven x = if (x `mod` 2 == 0) then Just x else Nothing 

complete :: Maybe String
complete =  (return "complete")

valid = 20 :: Int
invalid = 25 :: Int

withDo :: Int -> Maybe String
withDo value = do
	x <- isEven value
	_ <- lessThanHundred x
	complete

pipeline :: Int -> Maybe String
pipeline value = 
	isEven value >>= (\x ->
	lessThanHundred x >>= (\_ ->
complete))

Interesting Asides

Bret Victor on a better programming environment:

What a Monad is not

...and while addition and multiplication are both monoids over the positive natural numbers, an oven is a monoid over food (Burned pizza doesn't concern us, here: Food stays food, even if you don't want to eat it.), a monad is a monoid object in a category of endofunctors: return is the unit, and join is the binary operation. It couldn't be more simple. If that confuses you, it might be helpful to see a Monad as a lax functor from a terminal bicategory.

Monad operations (bind and return) have to be non-strict in fact, always!

Instead, every monad is an applicative functor (as well as a functor). It is considered good practice not to use >>= if all you need is <*>, or even fmap.

Monads are commonly used to order sequences of computations. But this is misleading. Just as you can use monads for state, or strictness, you can use them to order computations. But there are also commutative monads, like Maybe, that don't order anything. So ordering is not in any way essential to what a monad is.

http://www.haskell.org/haskellwiki/What_a_Monad_is_not

Clone this wiki locally