gpt4 book ai didi

haskell - 为什么:p freeze in GHCi when I give it this corecursive value?

转载 作者:行者123 更新时间:2023-12-04 01:07:14 28 4
gpt4 key购买 nike

我已经定义了无限列表的无限列表 pathCounts和有限列表的无限列表pathCounts' :

import Data.Function (fix)

nextRow xs = fix $ \ys -> zipWith (+) xs (0:ys)

pathCounts = repeat 1 : map nextRow pathCounts
pathCounts' = map (take 100) pathCounts

进入 ghci,如果我都没有评估过,我可以使用 :p成功:
ghci> :p pathCounts
pathCounts = (_t1::[[Integer]])
ghci> :p pathCounts'
pathCounts' = (_t2::[[Integer]])

但是如果我评估 pathCounts'部分,然后 :p卡住在 pathCountspathCounts' 上仍然成功:
ghci> head . head $ pathCounts'
1
ghci> :p pathCounts'
pathCounts' = (1 : (_t4::[Integer])) : (_t5::[[Integer]])
ghci> :p pathCounts
^CInterrupted.

我希望 :p pathCounts打印与 :p pathCounts' 相同,因为我只对它进行了部分评估。为什么它不起作用?

最佳答案

I'd expect :p pathCounts to print the same as :p pathCounts', as I've only partially evaluated it.



啊,但这就是有趣的地方!事实上,您已经全面评估了 pathCounts 的(无限长)头部。 .让我们举一个稍微小一点的例子来简化讨论:
> let v = repeat 1 :: [Int]
> head v
1
> :p v
^C

我声称在全面评估后 head v ,其实是 v也得到了充分的评价。这是因为,在内存中, v是一个循环单链表。因此,如果您已经评估到足以知道第一个元素,那么就没有什么可以评估的了!

结果是当你向 :print 询问时它,GHC 适本地尝试构造一个代表结构的所有评估部分的字符串——显然不能,因为它永远不会停止遍历。 ( :p 根本无法在结构中指示共享。)

相比:
> let x = 1 :: Int; v = (x, x)
> fst v
1
> :p v
(1,1)

虽然您只要求评估 v 的第一部分, 实际上所有 v这里已经评估过了,所以 :p全部打印出来——并且不表示第一部分和第二部分之间存在的共享。

现在,怎么来 pathCounts'没有同样的问题吗?好吧,事情就是这样,虽然 map f (repeat x) = repeat (f x)是一个表示正确的等式,在 Haskell 的 GHC 实现中,该等式在操作上并不健全——和 :p完全是关于操作语义的,而对指称语义嗤之以鼻。特别是, map不(不能)观察到 repeat x 中存在的共享;因此它产生一个非循环无限列表。由于 map f (repeat x)共享较少,强制 map f (repeat x) 的一部分不会产生完全评估的内存表示。

关于haskell - 为什么:p freeze in GHCi when I give it this corecursive value?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21732349/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com