I am learning about the guard function from the book 'Learn You a Haskell for Great Good!' by Miran Lipovaca.
For the following example:
ghci> [1..50] >>= (\x -> guard('7' `elem` show x) >> return x)
[7, 17, 27, 37, 47]
I know that guard takes a Boolean value, and if the value is True, guard takes () and puts it in a minimal default context and succeeds.
If the value is False, then guard makes a failed monadic value.
However, I don't understand how guard works in the above example to create the resulting list [7, 17, 27, 37, 47]. What is passed as x in the lambda function, is it 1? Further, if ('7' `elem` show x) evaluates to False, then wouldn't the empty list be returned? How exactly does the final result list come to be?
In the list
Monadinstance:>>=isconcatMapwith the arguments flippedguard conditionis equivalent toif condition then [()] else []And in any
Monadinstance,a >> b=a >>= \_ -> b, so in the list instance this is equivalent toconcatMap (\_ -> b) a.Therefore your code desugars to this:
So the outer
concatMapproduces as an intermediate value a list of 50 elements, each being a list, which is a singleton list of the input value if its string representation contains a digit7, or else the empty list:Which is then concatenated to produce the final result
[7, 17, 27, 37, 47].It’s each element of the input list,
1through50.The inner
concatMapproduces[x]if the condition is true and[]if the condition is false, becauseguardproduces a list of one element (the dummy()) if the condition is true and an empty list if it’s false—this may be easier to see if you rephrase it as an equivalent: