我正在浏览Learn You Some Haskell。在关于递归函数的章节中,作者重新定义了标准库中的两个:
take' :: (Num i, Ord i) => i -> [a] -> [a]
take' n _
| n <= 0 = []
take' _ [] = []
take' n (x:xs) = x : take' (n-1) xs
repeat' :: a -> [a]
repeat' x = x:repeat' x
字符串
我不明白为什么take’ 5 (repeat’ 3)
不会永远运行。我理解lazy eval,但在这种情况下,我认为repeat’
将永远被调用。take’
如何限制它?
2条答案
按热度按时间jgzswidk1#
大多数Haskell都有一个很好的特性,你可以简单地用它们的定义替换表达式。
我们可以使用此属性来推理您提供的示例:
字符串
r7knjye22#
在Haskell中,惰性求值使
take'
函数能够处理像repeat'
生成的无限列表。关键是Haskell只计算需要的内容。当您调用take' 5 (repeat' 3)
时,它只生成和计算无限列表的前五个元素,允许有限递归。惰性求值确保Haskell不会尝试预先生成整个无限列表,在产生所需的元素之后,使递归能够终止。