To put into context, I was converting a list comprehension (from there) doing "pattern filtering" to its monadic counterpart (do and bind), then I meet an exception.
I start with these definitions (bf holds for breadthFirst),
context, data and helper
data Tree a = Leaf | Node a (Tree a) (Tree a) deriving Show
let test = Node 1 (Node 2 (Node 4 Leaf Leaf) Leaf) (Node 3 Leaf (Node 5 Leaf Leaf))
let nextChild = concatMap (\x -> case x of; Leaf -> []; Node n l r -> [l,r])
function to test
let bfLc xs | null xs = [] | otherwise = [ n | Node n _ _ <- xs] ++ (bfLc $ nextChild xs)
let bfDo xs | null xs = [] | otherwise = (do {Node n _ _ <- xs; return n}) ++ (bfDo $ nextChild xs)
let bfBind xs | null xs = [] | otherwise = (xs >>= \(Node n _ _) -> [n]) ++ (bfBind $ nextChild xs)
And I do these evaluations,
bfLc [test]
[1,2,3,4,5]
bfDo [test]
[1,2,3,4,5]
bfBind [test]
[1,2,3,4*** Exception: <interactive>:103:53-72: Non-exhaustive patterns in lambda
But I learned from there
The do syntax provides a simple shorthand for chains of monadic operations. The essential translation of do is captured in the following two rules:
do e1 ; e2 = e1 >> e2 do p <- e1; e2 = e1 >>= \p -> e2
Why does bfBind
fail contrary to bfDo
despite they are equivalent ?
Personally, I was expected they all failed, I don't know why list comprehension or Do notation succeed ? (Then if you can answer also this sub question)
Thanks.