Haskell:列表理解评估的意外结果

时间:2017-12-10 19:14:58

标签: haskell list-comprehension

我只是在学习一些Haskell,在repl中使用列表推导时,我无法理解如何在以下代码中生成元组("bird", 4)

*Main> :{
*Main| [(x, y) | x <- ["cat", "dog", "bird"]
*Main|         , y <- [1..length x]]
*Main| :}
[("cat",1),("cat",2),("cat",3),("dog",1),("dog",2),("dog",3),("bird",1),("bird",2),("bird",3),("bird",4)]

据我所知,x的长度永远不会超过3,我希望看到bird的三个元组,因为cat为3,dog为3 {1}}。

为什么会这样? Haskell看到了什么?

1 个答案:

答案 0 :(得分:1)

简短回答x将列表的作为值,列表本身。

你可以在Haskell中看到列表理解,就像在Python中完成一样:

[(x, y) | x <- ["cat", "dog", "bird"]
        , y <- [1..length x]]

相当于:

[(x,y) for x in ["cat", "dog", "bird"] for y in range(1, 1+len(x))]

或以先前的方式:

result = []
for x in ["cat", "dog", "bird"]:
    for y in range(1, 1+len(x)):
        result.append((x,y))

因此,我们在列表x上使用["cat", "dog", "bird"]进行迭代,然后对于每个值x进行迭代,我们使用range(1, 1+len(x))迭代y。对于列表的最后一项,"bird"因此意味着length的{​​{1}} / len为4(因为鸟是一个包含四个字符的单词)。因此"bird"将为鸟类迭代四次。

如果您想要y长度为minimum,可以使用:

x

如果您想要获取字符串列表的[(x, y) | x <- ["cat", "dog", "bird"] , y <- [1..minimum (map length) ["cat", "dog", "bird"]]] ,您可以使用该列表的length,所以:

length