首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在列表理解中如何正确使用seq?

在列表理解中如何正确使用seq?
EN

Stack Overflow用户
提问于 2021-04-29 17:31:33
回答 1查看 57关注 0票数 1

我试图在列表理解中使用seq来强制对生成的元素进行计算,但是:sprint告诉我,我的列表实际上是没有计算的。例如:

代码语言:javascript
复制
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似乎运行正常:

代码语言:javascript
复制
Prelude> let xs = map (+1) [1..10] :: [Int]
Prelude> :sprint xs
xs = _
Prelude> seq xs ()
()
Prelude> :sprint xs
xs = _ : _

为什么我的seq不能工作?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-29 17:36:52

您没有给lst一个具体的类型,所以每次使用它时,ghci都是一个新的实例/值( GHCi将为它选择一个默认类型)

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

代码语言:javascript
复制
<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],它应该可以工作:

代码语言:javascript
复制
> 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 = _ : _

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

编辑( @dfeuer )指出,关于参数/不可见函数的评论可能是误导的,甚至是错误的。

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

在上面的示例中,隐式Num约束(019+)要求对所涉及类型的Num实例使用这样的字典。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67322367

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档