Search code examples
haskellpurescript

Need guard clause syntax for this list comprehension using do notation


I found this function in a pure script tutorial and I'm trying to convert to Haskell because sometimes it would be nice to do complicated list comprehension in this way, I think. I'm stuck on the guard line (commented out) that only lets right angle triangles through to the solution set.

triples :: Int -> [[Int]]
triples n = do
  z <- [1 .. n]
  y <- [1 .. z]
  x <- [1 .. y] 
--  guard x * x + y * y == z * z ↼↽ not sure how to do this
  return [x, y, z]

in purescript:

-- Find Pythagorean triples using an array comprehension.
triples :: Int -> Array (Array Int)
triples n = do
  z <- 1 .. n
  y <- 1 .. z
  x <- 1 .. y
  guard $ x * x + y * y == z * z
  pure [x, y, z]

Solution

  • The solution is nearly the same code:

    import Control.Monad (guard)
    
    triples :: Int -> [[Int]]
    triples n = do
      z <- [1 .. n]
      y <- [1 .. z]
      x <- [1 .. y] 
      guard $ x * x + y * y == z * z
      return [x, y, z]
    

    Just remember to import guard. Note that, in this case you can pretend that guard is defined as:

    guard :: Bool -> [()]
    guard True  = [()]
    guard False = []
    

    The library definition is more general, but it does not matter here. In principle, you could even use this definition for guard and avoid importing from the library.