Skip to content

Instantly share code, notes, and snippets.

@krishnabhargav
Last active August 29, 2015 14:10
Show Gist options
  • Save krishnabhargav/b4f997d3d50d685e2343 to your computer and use it in GitHub Desktop.
Save krishnabhargav/b4f997d3d50d685e2343 to your computer and use it in GitHub Desktop.
monad examples that helped me understand .. in haskell
Functor & Fmap.
---------------
Lets start with fmap. fmap is defined in a Functor.
fmap takes a function and a box.
fmap then extracts the content from the box,
applies the function on the content and puts the result back into the box.
The signature of the fmap is
> fmap :: Functor f => (a -> b) -> f a -> f b
List & Maybe are both Functors.
So,
> fmap (\x -> x + 1) (Just 1)
should return Just 2 as the answer.
And,
> fmap (\x -> Just x) [1..10]
returns a list of (Maybe n) where n ranges from 1 to 10.
One more example,
> fmap (\x -> x `mod` 2 == 0) [1..10]
will return a list of booleans indicating if the number is divisible by 2 or not. So in this sense, fmap is basically a map.
Basically, fmap maintans the shape.
MONADS
------
Monads define two basic methods: >>= (bind) and return.
bind take two parameters
1. monad m a (eg: Just 20)
2. function that takes parameter of type a and returns monad of the same type m for b. (eg: the function should return same monad type)
bind then returns some monad b.
For example, if lets use bind to increment Just 3 to get Just 4.
> (>>=) (Just 3) (\x -> Just (x+1))
You can write the same as:
> (Just 3) >>= (\x -> Just (x+1))
One more example, use bind to convert Just n to Just [n]
> (Just 3) >>= (\x -> Just [x])
Now, lets apply bind to a list of integers and get a list of Maybe n
> [1,2,3] >>= (\x -> [Just x])
Now, lets apply bind again to the list of maybe integer to get a list of integers
> [Just 1, Just 2, Just 3] >>= (\x -> [Data.Maybe.fromJust x])
Notice that in the bind's 2nd paramter (function) we are always returning the same list.
Another way to apply the >>= is to use the do notation and the return function of the Monad.
> [1,2,3] >>= (\x -> [Just x]) can be written as
> do x <- [1,2,3]; return (Just x)
Basically, >>= works as fmap/map for lists except the >== expects a [] back in the function passed.
so the above could be
> map (\x -> Just x) [1,2,3]
To be precise, >>= works like a concatMap (thanks again @tailcallingdev)
> concatMap (\x -> [x+1]) [1,2,3]
> [1,2,3] >>= (\x -> [x+1])
> map (\x -> x+1) [1,2,3]
> fmap (\x -> x+1) [1,2,3]
Coming back to the maybe monad examples.
If you have
> (Just 3) >>= (\x -> Just (x*x))
can be written as
> do x <- Just 3; return (x*x)
or in a full haskell code.
> msquare m = do
> x <- m
> let y = x*x
> return y
You will use the above function as
> msquare (Just 3) -- Just 9 will be the answer
In C# style (incomplete, thanks @TailCallingDev) definition, a bind function would be
interface Monad[T] {
Monad[K] Bind[K](Monad[T] m, Func[T, Monad[K]] applier);
K Return(K val);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment