无法理解列表理解

Syn*_*ose 12 haskell list-comprehension pythagorean

我刚开始学习haskell(字面意思,今晚!)而且我在理解列表推导的逻辑方面有点麻烦,更具体地说是<-运算符.了解一些Haskell的一个小例子查找长度小于10的所有元组:

ghci> let triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ]
Run Code Online (Sandbox Code Playgroud)

我最初的理解是这些都会一起增加,但在看到输出后我真的不理解这些列表的递增方法.另一个似乎让我得到的例子是:

ghci> let rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
Run Code Online (Sandbox Code Playgroud)

我真的很感激对这些的一点解释,感谢你对我缺乏haskell情报的耐心.

Wil*_*ess 20

[为"list of",|"for",<-"in",,"and".

枚举以嵌套方式完成.[ (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)
Run Code Online (Sandbox Code Playgroud)

但是在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]
      )))
Run Code Online (Sandbox Code Playgroud)

所以你真的可以在这里看到嵌套结构.(>>=)也不是什么神秘的事.读>>=作"fed into"或"push Through",虽然它的官方名称是"bind".它被定义为(列表)为

(xs >>= f) = concatMap f xs = concat (map f xs)
Run Code Online (Sandbox Code Playgroud)

f这里按顺序称为(by map)每个元素xs.它必须生成列表才能与它们结合使用concat.由于(例如)[]消除了空列表,因此从最终输出中消除了所有未通过测试的元素.concatconcat [[1], [], [3]] == [1,3]


有关完整翻译,请参阅Haskell 98报告的第3.11节"列表推导".通常,列表推导可以包含模式,而不仅仅是变量名称.理解力

[e | pat <- ls, ...]  
Run Code Online (Sandbox Code Playgroud)

被翻译为

ls >>= (\x -> case x of pat -> [e | ...] ;
                        _   -> [] )
Run Code Online (Sandbox Code Playgroud)

pat某些模式在哪里,x是一个新变量.时,有一个不匹配的图案,一个空列表产生(而不是运行时间错误),并且元件xls被跳过.这对于其他基于模式的过滤非常有用,例如[x | Just x <- ls, even x],所有Nothings in ls都被忽略了.

  • 详细而且非常清楚,真的帮助我理解了这些材料.非常感谢! (5认同)