--class Monad List where -- return x = [x] -- as >>= f = concat (map f as) --We will use guard as an indicator if a predicate is sat --The type of guard could be from bool to list of anything --so long as guard on False returns empty list and guard --on true returns a non-empty list guard :: Bool -> [()] guard True = [()] guard False = [] triples = [1..20] >>= (\z -> --z is some int between 1 and 20 [1..z] >>= (\x -> --x is some int between 1 and z [x..z] >>= (\y -> --y is some int between x and z --The next bind takes a list of ()'s. Each one gets --mapped to the return. The return gives a triple in a --list. Thus each () produces a list of list of triples --which >>= collapses to a single list. guard (x^2 + y^2 == z^2) >>= (\_ -> return (x, y, z))))) --The same function as above but using the do notation. trips = do z <- [1..20] --This list can be unbounded because of laziness. x <- [1..z] y <- [x..z] guard (x^2 + y^2 == z^2) return (x,y,z) --I wonder why the only values returned are ones with n=2? fermat = do c <- [1..20] a <- [1..c] b <- [a..c] n <- [2..20] guard (a^n + b^n == c^n) return (a, b, c, n) main = do print $ fermat