the task ist to translate this
f = do
c <- [1 .. 200]
b <- [1 .. 200]
guard (c >= b)
a <- [1 .. 200]
guard (a >= b && (c^2 - a^2 == b^2))
return (a,b, c)
into a non-sugar verion.
I think I got most of it figured out, but I’m stuck in the middle with a problem I need to fix before I can continue. So far I have:
f = [1 .. 200] >>= \c ->
[1 .. 200] >>= \b ->
if (c >= b)
then [1 .. 200] >>= \a -> if (a >= b && (c^2 - a^2 == b^2))
then return(a,b,c)
else return ()
else return ()
which does not compile. When I put in (a,b,c) for the return, it compiles, but obviously it does not give the expected result anymore. How do I return “nothing” in the else branches?
If I put in ((),(),()) as the return values, the compiler gets a “No instance for (Num [a]) arising from the literal ‘1’”
Instead of
return (), which is[()], you must produce an empty list, soelse []or, with the genericguardimplementationelse mzero.The success branch produces a list of triples,
[(Int,Int,Int)](orInteger, or anotherNumtype), so the failure branches must produce the same. Since failure means that no triple is found, they shall produce an empty list.Note that in the
[]monad,return xis just[x]andmzero(fromMonadPlus) is the same asfail whatever, namely[].