take 2 $ [1..] 在haskell 中如何工作?

程序员

我们知道 $ 运算符绑定了最松散的,并且也关联到了右边,这意味着 [1..] 应该首先被评估,因此,它不应该陷入无限循环吗?为什么它甚至完全停止?

数学兰花

这里$是红鲱鱼。take 2 $ [1..]与 完全相同take 2 [1..]$仅影响一种说法是什么; 它对评估事物的时间完全没有影响。

(例如:

print 2 + 2         ==> (print 2) + 2 {- Doesn't work. -}
print $ 2 + 2       ==> print (2 + 2) {- Works. -}

美元会影响print是争论+还是相反。美元本身不评估任何东西。)

这里的“最顶层”函数是take,所以我们首先评估它。的定义take可以这样写:

take 0 xs = xs
take n xs =
  case xs of
    x : xs' -> x : take (n-1) xs'
    []      -> []

假设长度不为零,它所做的第一件事就是case xs of ...,这意味着xs(在这种情况下[1..])必须评估以确定它是 a:还是 a []这样做,我们发现(在恒定时间内)xs = 1 : [2..],因此适用第一种情况。

可以这样写...

take 2 [1..]
take 2 (1 : [2..])
1 : take (2-1) [2..]
1 : take 1 [2..]
1 : take 1 (2 : [3..])
1 : 2 : take (1-1) [3..]
1 : 2 : take 0 [3..]
1 : 2 : []

(我仍然认为很遗憾没有人想出一个工具来自动生成这样的跟踪......它可以让一些人不混淆,并且可能非常适合调试......)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章