无法理解列表理解 [英] Having trouble understanding list comprehensions

查看:145
本文介绍了无法理解列表理解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习haskell(从字面上理解,今晚!),并且我在理解列表推导的逻辑,特别是< - 运营商。 学习一些Haskell 的小示例查找长度小于10的所有元组:

  ghci>让三角形= [(a,b,c)| c < -  [1..10],b < -  [1..10],a < -  [1..10]] 

我最初的理解是这些都会一起增加,但在看到输出结果后,我确实不理解这些列表的递增方法。另一个似乎让我感到满意的例子是:

  ghci>让rightTriangles = [(a,b,c)| c < -  [1..10],b < -  [1..c],a < -  [1..b],a ^ 2 + b ^ 2 == c ^ 2] 

我非常感谢他们对这些问题的一些解释,感谢您对我缺乏哈斯克尔情报的耐心。

解决方案阅读 [ aslist of, | 为for,< - 为in,为and 。

枚举以嵌套方式完成。 [(a,b,c)| c < - [1..10],b < - [1..c],a < - [1..b],a ^ 2 + b ^ 2 == c ^ 2] 真的是

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ c $从c到1到步骤1步骤1
从1到步骤1 :
for a from 1 to b step 1:
if(a ^ 2 + b ^ 2 == c ^ 2):
emit(a,b,c)

在Haskell中,上述是通过以下翻译实现的:

  [1..10]>> =(\c->  - ('c'的函数,产生... 
[1。 (b')的函数,产生...
[1..b]>> =(\a-> gtc) ; - ('a'的一个函数,产生...
如果a ^ 2 + b ^ 2 == c ^ 2那么[(a,b,c)] else []
- - 或:[(a,b,c)| a ^ 2 + b ^ 2 == c ^ 2]
)))

所以你真的可以在这里看到嵌套的结构(>> =)也不是什么神秘的东西。 $ c>>> = 作为fed into或push through它的正式名称是绑定。它被定义为(对于列表)

pre $ (xs>> = f)= concatMap f xs = concat(map f xs)

f 这里叫做在 xs 的每个元素上按顺序排列 map )。它必须生成列表,以便它们可以与 concat 组合。由于 concat (例如 concat [[1],[所有未通过测试的元素都会从最终输出中消除。






$ b $ hr>

有关完整翻译,请参阅部分3.11,列表理解,Haskell 98报告。一般来说,列表理解可能包含一个模式,而不仅仅是一个变量名。理解

  [e | pat < -  ls,...] 

被翻译为

  ls>> =(\ x  - > case x of pat  - > [e | ...]; 
_ - > [])

其中 pat 是一些模式, x 是一个新变量。当有一个模式不匹配时,会产生一个空列表(而不是运行时错误),并且 ls x $ c>被跳过。这对于另外的基于模式的过滤很有用,例如, [x |只要x < - ls,甚至x] 其中 ls 中的所有 Nothing 被安静地忽略。


I've just started learning haskell(literally, tonight!) and I'm having a little trouble understanding the logic of list comprehensions, more specifically the <- operator. A little example on Learn You Some Haskell Finds all tuples that have a length less than 10:

ghci> let triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ]

my initial understanding was that these would all increment together, but after seeing the output I really dont understanding the incrementing method for these lists. Another example that seems to get me is:

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

I would really appreciate a little explanation on these, thanks for your patience with my lack of haskell intelligence.

解决方案

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

The enumerations are done in nested fashion. [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2] is really

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)

In Haskell though, the above is achieved by the following translation

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

so you really can see the nested structure here. (>>=) is nothing mysterious too. Read >>= as "fed into" or "pushed through", although its official name is "bind". It is defined (for lists) as

(xs >>= f) = concatMap f xs = concat (map f xs)

f here is called (by map) upon each element of xs, in order. It must produce lists so that they could be combined with concat. Since empty lists [] are eliminated on concat (e.g. concat [[1], [], [3]] == [1,3]) all the elements that do not pass the test are eliminated from the final output.


For the full translation see section 3.11, List Comprehensions, of the Haskell 98 Report. In general a list comprehension may contain a pattern, not just a variable name. The comprehension

[e | pat <- ls, ...]  

is translated as

ls >>= (\x -> case x of pat -> [e | ...] ;
                        _   -> [] )

where pat is some pattern, and x is a fresh variable. When there's a pattern mismatch, an empty list is produced (instead of a run-time error), and that element x of ls is skipped over. This is useful for additional pattern-based filtering, like e.g. [x | Just x <- ls, even x] where all the Nothings in ls are quietly ignored.

这篇关于无法理解列表理解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆