首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据结构的延迟计算

数据结构的延迟计算
EN

Stack Overflow用户
提问于 2014-07-25 18:48:41
回答 1查看 117关注 0票数 6

我在haskell读到关于懒惰评估的文章,我有一个问题。例如,我们有以下计算:

代码语言:javascript
复制
Prelude> let x = 1 + 1 :: Int
Prelude> let y = (x,x)

在得到x值之后

代码语言:javascript
复制
Prelude> :sprint x
x = _

还没有评估过。好了,现在让我们得到y的值:

代码语言:javascript
复制
Prelude> :sprint y
y = (_,_)

它也是未评估的,因为y依赖于x and it's unevaluated。现在,让我们尝试使用相同的示例,但不使用::Int

代码语言:javascript
复制
Prelude> let x = 1 + 1
Prelude> let y = (x, x)
Prelude> :sprint y
y = _

为什么y值是_而不是(_, _)当我们尝试不使用::Int

我看到他们有不同的类型:

代码语言:javascript
复制
Prelude> let x = 1 + 1
Prelude> :t x
x :: Num a => a
Prelude> let x = 1 + 1 :: Int
Prelude> :t x
x :: Int

但是为什么y的值依赖于它呢?

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-25 19:12:46

当您指定x具有Num a => a类型时,编译器不可能知道在执行1 + 1时要使用哪个Num实例。相反,它所做的是使用默认。GHC为某些类型定义了默认类型,这样当无法确定使用哪种具体类型时,GHC仍然可以给出有意义的结果,而不会引发错误。所以当你看到

代码语言:javascript
复制
> let x :: Num a => a
|     x = 1 + 1
> x
2
> :sprint x
x = _

这是因为GHCi选择Integer作为Num的默认类型,但在执行此操作时,它不会将结果存储在x的内存位置,因为没有一种方法可以知道这是否是正确的答案。这就是为什么您看到:sprint中的x = _,它实际上没有计算x :: Num a => a,而是计算了x :: Integer。您甚至可以自己处理这个默认值:

代码语言:javascript
复制
> newtype MyInt = MyInt Int deriving (Eq)
>
> instance Show MyInt where
|     show (MyInt i) = show i
> instance Num MyInt where
|     (MyInt x) + (MyInt y) = MyInt (x - y)
|     fromInteger = MyInt . fromInteger
>
> default (MyInt)
> x
0

现在我们已经说过了,1 + 1 = 0!请记住,您可能永远不会使用GHC的这个功能,但是了解它是很好的。

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

https://stackoverflow.com/questions/24962582

复制
相关文章

相似问题

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