In a comment to one of my answers, SO user sdcwc essentially pointed out that the following code:
comb 0 = [[]] comb n = let rest = comb (n-1) in map ('0':) rest ++ map ('1':) rest
could be replaced by:
comb n = replicateM n "01"
which had me completely stunned.
Now I am looking for a tutorial, book or PDF that teaches these advanced concepts. I am not looking for a "what's a monad" tutorial aimed at beginners or online references explaining the type of replicateM
. I want to learn how to think in monads and use them effectively, monadic "patterns" if you will.
If you would like to take a fundamentals-focused approach towards learning Haskell, Introduction to Functional Programming could be the choice for you. It is an online course taught by Erik Meijer that uses Haskell to teach you how to think about programs and write them in any functional programming language.
The mathematician Roger Godement was the first to formulate the concept of a monad (dubbing it a "standard construction") in the late 1950s, though the term "monad" that came to dominate was popularized by category-theorist Saunders Mac Lane.
Take functions like sequence
, filterM
, liftM2
, join
and think how they work for each monad IO
, []
, (->) a
, Writer
, State
. For example, sequence
for IO monad executes IO actions sequentially:
[IO a] -> IO [a]
Write the signature and try to use them. Some combinations are interesting, some less.
Example for filter:
{-# LANGUAGE NoMonomorphismRestriction #-} import Control.Monad import Control.Monad.State import Control.Monad.Reader a = filterM (\x -> do putStrLn $ "Put " ++ show x ++ "?" fmap (=="Y") getLine) b = filterM (const [False,True]) c m xs = runState (filterM k xs) 0 where k x = do a <- get let p = a + x <= m when p $ put (a+x) return p d = filterM (flip id)
a
filters the list using IO - it asks the user about each item.
b
filters the list nondeterministically - every item is nondeterministically included and not included. As a result, you get powerset. (Try it!)
c
filters the list, maintaining state. In this case this is greedy knapsack - you've got knapsack of capacity m
and want to insert as many items from xs
.
d
filters the list, maintaining a read-only state. This isn't interesting. I used the filtering function as the state, and this gives flip filter
.
A single function filterM
can do all those things.
If you'll write similar code for other functions, you'll get enough intuition to notice monadic functions in other places. For example, how to get the following function?
dup f x = f x x
and what about dup' f x = f x x x
?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With