【问题标题】:Haskell. Strict application $!哈斯克尔。严格申请$!
【发布时间】:2009-10-17 12:51:52
【问题描述】:

我执行下一段代码:

(take 10) $! [1,2..]

这是什么?我想,ghc 会终止,因为我说“评估 [1,2..] 力”。但我得到了结果“[1,2,3,4,5,6,7,8,9,10]”。

【问题讨论】:

  • 根据您的图像,您 正在 得到 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 应有的效果。你为什么说你得到了结果“1”?
  • 对不起。最初我想打印另一个例子。

标签: optimization haskell lazy-evaluation


【解决方案1】:

因此,您希望对列表进行全面评估。 ($!) 是根据seq 实现的,并且seq 根据文档“仅”评估为头部标准形式。只有当值为undefined时才会有所不同:

Prelude> take 0 undefined
[]
Prelude> take 0 $! undefined
*** Exception: Prelude.undefined

函数的参数是严格的,如果

f undefined = undefined

这并不意味着该论点已以急切的方式进行了全面评估。你想要的是DeepSeq 之类的东西。

GHCi, version 6.10.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling DeepSeq          ( deepSeq.lhs, interpreted )
Ok, modules loaded: DeepSeq.
*DeepSeq> take 1 $!! [1,2,undefined]
*** Exception: Prelude.undefined
*DeepSeq> 

您在DeepSeq 中使用$!! 的示例将永远运行。

【讨论】:

  • 你能给我这个文件吗? )
  • 我只是指“seq :: a -> b -> b”的文档,它说“将其第一个参数评估为头部范式,然后返回其第二个参数作为结果。”
【解决方案2】:

强制评估只会确保其参数[1,2..] 不是底部。 [1,2..] 匹配 (1:_),所以它不是底部,并且计算将按预期进行,返回 [1,2,3,4,5,6,7,8,9,10]

不知道你从哪里得到那个 1 结果;您介意复制粘贴 GHCi 会话的摘录吗?

【讨论】:

  • 很遗憾,新用户不发布图片。
  • 当然对于两行文本,您可以将它们复制为文本;)
【解决方案3】:

你是不是打错字了?在 GHCi 6.8.2 下,无论有无括号,它都适用于我...

GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
($Loading package base ... linking ... done.
Prelude> take 10 $! [1..]
[1,2,3,4,5,6,7,8,9,10]
Prelude> (take 10) $! [1..]
[1,2,3,4,5,6,7,8,9,10]
Prelude> (take 10) $! [1,2..]
[1,2,3,4,5,6,7,8,9,10]

【讨论】:

  • My GHC 给我的结果与您的 ghc 相同。但这是结果不能让我满意。我想终止。当与具有多个参数的柯里化函数一起使用时,严格应用可用于强制对任何参数组合进行顶级评估。例如,如果 f 是具有两个参数的柯里化函数,则可以修改 f x y 形式的应用程序以具有三种不同的行为: (f $! x ) y 强制对 x (f x) $! 进行顶级评估y 强制对 y (f $! x) $! 进行顶层评估y 强制对 x 和 y 进行顶层评估
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多