2017-02-23 73 views
3

我是Haskell的新手,在尝试理解一些东西时玩弄。如果我这样做,我收到了一个问题:Haskell列表被冻结

list1 = [1..] 
list2 = [x | x <- list1, x <= 4] 
print list2 

返回[1,2,3,4。它没有末端括号,所以就好像列表正在加载或冻结一样。下面是它的外观:

Prelude> print list2 
[1,2,3,4 

这是怎么回事?

+7

假装你是GHCI。你的用户给你一个无限的列表,并要求你找到列表中小于或等于4的所有值。你会怎么做呢? (请记住,您不知道该列表是按顺序排列的。) – user2297560

+1

啊,是的,这是有道理的。有没有办法处理这样的无限列表和条件? – greenthumbtack

+1

你可以从'list1'获取4个元素(从字面上看'list2 = take 4 list1') – user28434

回答

7

知道列表单调递增,但Haskell没有。使用takeWhile,而不是一个列表理解,使list1可以停止正在评估一旦你找到一个值大于4

> list1 = [1..] 
> list2 = takeWhile (<= 4) list1 
> print list2 
[1,2,3,4] 
4

会发生什么事是list1仍在计算,并为list1谓词x <= 4的每个新元素被应用,这是false为每x4后。

因此,简言之:

印出list2解释需要计算list1,并检查各列表项,这是<= 4,因为list1是它的无穷计算必须采取无限长的时间。

2

您正在采取list1中的每个元素,并且对于每个小于4的元素,使其成为list2中的条目。看看你在list1有多少元素。