需要使用 do 符号的此列表理解的保护子句语法

Need guard clause syntax for this list comprehension using do notation

我在 pure script tutorial 中找到了这个函数,我正在尝试转换为 Haskell,因为我认为有时以这种方式进行复杂的列表理解会很好。我被困在只允许直角三角形通过解决方案集的警戒线上(已注释掉)。

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]

在纯脚本中:

-- 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]

解决方案几乎是相同的代码:

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]

记得导入guard。请注意,在这种情况下,您可以假装 guard 定义为:

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

库定义比较笼统,这里无所谓。原则上,您甚至可以将此定义用于 guard 并避免从库中导入。