A few days ago I was motivated to write a program in Haskell to test whether
three numbers form a Pythagorean triple. There is an obvious solution, of
course, but it’s always nice to shove monads in to problems that don’t need
them. In this case, though, I found that the resulting solution did more than
I had originally planned: if you pass the
pTriples function a list of
numbers, it will return a list of each Pythagorean triple that can be made
from numbers in the list (without replacement). Cool!
The code is based on a very nice puzzle solution.
import Control.Monad import Control.Monad.Trans.State select  =  select (x:xs) = (x, xs) : [(y, x:ys) | (y,ys) <- select xs] -- pTriples takes a list of integers and returns the list of -- Pythagorean triples that can be made from them, eg. -- pTriples [2, 3] is  -- pTriples [3, 4, 5] is [(3, 4, 5)] -- pTriples [3, 4, 9, 11] is  -- pTriples [3, 4, 9, 5] is [(3, 4, 5)] pTriples :: [Integer] -> [(Integer, Integer, Integer)] pTriples = evalStateT $ do a <- StateT select b <- StateT select c <- StateT select guard $ a <= b guard $ a*a + b*b == c*c return (a, b, c) isTriple = not . null . pTriples
Approx. 224 words, plus code