我有以下功能:
longer x y | y < 0 = True
| length x > y = True
| length x <= y = False
其中x
为[a]
型,y
为Int
型。
这个函数在有限列表中工作得很好,但是当我输入一个无限列表时,它不会计算并进入一个无限循环。我应该尝试其他什么方法?
我的尝试:
在longer [1..] 10
的情况下,我会从第一个值开始,比较列表的长度(所以[1]
)与10,如果长度较小,然后移动到前两个值,比较列表的(所以[1,2]
)长度与10,看到语句仍然是假的,移动到前三个值等。我认为递归可能是解决我这个问题的正确方法。
你看,如果一个列表被传递给一个函数,它可以是两种形状,要么是空的
length [] y = undefined
或者它由一个值和列表的其余部分组成
length (x:xs) y = undefined
这是仅有的两种情况,因为列表数据类型是这样定义的:
Prelude> :info []
data [] a = [] | a : [a] -- Defined in `GHC.Types'
因此,通过将原始问题分解为两个较小的部分,您已经取得了进展。您可能能够实现第一种情况(空列表)。但请注意,第二种情况也取得了进展。虽然以前您对原始列表x
一无所知(最好将其命名为xs
),但现在您知道原始列表的形状为x : xs
。这里x
是列表的第一项,xs
是剩下的列表。特别是,你现在知道,传递的列表至少是1的大小。不管剩下的列表是xs
,这都是正确的。现在可以实现
length (x:_) 0 = undefined
如果是,y
不为零的情况:
length (x:xs) y = undefined
你能问一个关于xs
和y
而不是x:xs
和y
的新问题吗?请记住,您知道xs
比x : xs
短一项。