【问题标题】:How to properly use seq In list comprehension? [duplicate]如何在列表理解中正确使用 seq? [复制]
【发布时间】:2021-04-29 17:31:33
【问题描述】:

我试图在列表推导中使用seq 来强制评估生成的元素,但:sprint 告诉我我的列表实际上没有被评估。例如:

Prelude> let foo a b = a + b
Prelude> let bar c = c + 1
Prelude> let lst = [bar $ foo x y | y <- [0..9], x <- [0..9]]
Prelude> :sprint lst
lst = _
Prelude> seq lst ()
()
Prelude> :sprint lst
lst = _

但其他人的map 似乎工作正常:

Prelude> let xs = map (+1) [1..10] :: [Int]
Prelude> :sprint xs
xs = _
Prelude> seq xs ()
()
Prelude> :sprint xs
xs = _ : _

为什么我的seq 不起作用?

【问题讨论】:

  • 你在编译的 *.hs 文件中没有这个问题,因为当编译器完成后,一切都会有一个具体的类型
  • @Carsten 谢谢,这对我有帮助!
  • GHCi&gt; :set +t 它将打印每个计算值的类型。所以你总能马上看到类型是多态的还是单态的。

标签: list haskell evaluation


【解决方案1】:

你没有给 lst 一个具体的类型,所以对于 ghci,它是一个新的 instance/value 每次你使用它(GHCi 会选择一个 default 类型它)

如果您没有更改任何内容,您甚至应该会看到如下警告:

<interactive>:19:1: warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Integer’
        (Show a0) arising from a use of ‘print’ at <interactive>:19:1-10
        (Num a0) arising from a use of ‘it’ at <interactive>:19:1-10
        (Enum a0) arising from a use of ‘it’ at <interactive>:19:1-10
    • In a stmt of an interactive GHCi command: print it

添加:: [Int],它应该可以工作:

> let foo a b = a + b
> let bar c = c + 1
> let lst = [bar $ foo x y | y <- [0..9], x <- [0..9]] :: [Int]
> :sprint lst
lst = _
> seq lst ()
()
> :sprint lst
lst = _ : _

我喜欢将 泛型类型 视为具有额外的 invisible 参数:类型参数的类型 - 所以它更像是一个函数而不是一个值;)(当然实际上它并不完全像这样,但它可以帮助我解决这样的问题)


编辑 @dfeuer 指出有关参数/不可见函数的评论可能具有误导性甚至是错误的。

遗憾的是,我不能声称我真的知道 GHCi 是如何处理这个问题的(当我找到来源时,我很乐意添加一些东西),但到目前为止,我的直觉是,在所有 字典之前,GHCi 确实/不能创造价值 类型类约束是已知的 - 所以如果没有约束,它可以并且将创建值(在运行时没有类型,所以这没问题)。

在上面的例子中,隐含的Num 约束(019+)需要这样一个 字典 用于所涉及的 Num 实例输入。

【讨论】:

  • 是的!太感谢了!我想这意味着如果我在我的 .hs 文件中明确声明一个变量为[Int],那么seq 也应该在它上面正常工作?
  • 正如我在上面评论的(对不起,我的不好)-在编译的文件中,您永远不会遇到该问题-当您最终 使用它必须具有 的值时具体 类型,当然它应该是您指向的固定值 - 这实际上就是 GHCi 处理泛型类型的方式
  • remark:当然,如果您在 .hs 文件中这样定义它并将其加载到 GHCi 中,您最终会再次出现在这里 - 但如果您将文件编译到程序中并运行它,您将不会t - 抱歉,如果不清楚
  • 关于不可见参数的说法不够精确,以至于给人以错误的印象。 map Const "Hello!" 的类型为 [Const Char a],但它仍然在操作上只有一个值。
  • @Carsten,绝对不在报告中。字典是一个实现问题。我不知道你在哪里可以读到它,但你可能会发现看看 Richard Eisenberg 的一篇关于可能存在的不同类型论点的演讲会很有趣。可见与推断、相关与不相关(扩展到线性)、类型与术语。我手头没有链接,但我认为 YouTube 上的某个地方至少有一个视频。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多