Read [
作为“列表”,|
至于”,<-
作为“在”,,
作为“和”。
枚举是在nested时尚。[ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
是真的
for c from 1 to 10 step 1:
for b from 1 to c step 1:
for a from 1 to b step 1:
if (a^2 + b^2 == c^2):
emit (a,b,c)
但在 Haskell 中,上述内容是通过以下翻译实现的
[1..10] >>= (\c-> -- (a function of 'c', producing ...
[1..c] >>= (\b-> -- (a function of 'b', producing ...
[1..b] >>= (\a-> -- (a function of 'a', producing ...
if a^2+b^2==c^2 then [(a,b,c)] else []
-- or: [(a,b,c) | a^2+b^2==c^2]
)))
所以你真的可以在这里看到嵌套结构。(>>=)
也没什么神秘的。读>>=
尽管其正式名称是“绑定”,但它被称为“馈入”或“推入”。它(对于列表)定义为
(xs >>= f) = concatMap f xs = concat (map f xs)
f
这里被称为(由map
) 对每个元素xs
, 为了。它必须产生lists这样它们就可以与concat
。由于列表为空[]
被淘汰于concat
(e.g. concat [[1], [], [3]] == [1,3]
)所有未通过测试的元素都会从最终输出中消除。
完整翻译请参见第 3.11 节,列表推导式 http://www.haskell.org/onlinereport/exps.html#sect3.11,Haskell 98 报告。一般来说,列表推导式可能包含模式,而不仅仅是变量名。领悟
[e | pat <- ls, ...]
被翻译为
ls >>= (\x -> case x of pat -> [e | ...] ;
_ -> [] )
where pat
是某种模式,并且x
是一个新鲜变量。当模式不匹配时,会生成一个空列表(而不是运行时错误),并且该元素x
of ls
被跳过。这对于额外的基于模式的过滤很有用,例如[x | Just x <- ls, even x]
哪里所有的Nothing
s in ls
都被悄悄忽视。