我在haskell读到关于懒惰评估的文章,我有一个问题。例如,我们有以下计算:
Prelude> let x = 1 + 1 :: Int
Prelude> let y = (x,x)在得到x值之后
Prelude> :sprint x
x = _还没有评估过。好了,现在让我们得到y的值:
Prelude> :sprint y
y = (_,_)它也是未评估的,因为y依赖于x and it's unevaluated。现在,让我们尝试使用相同的示例,但不使用::Int
Prelude> let x = 1 + 1
Prelude> let y = (x, x)
Prelude> :sprint y
y = _为什么y值是_而不是(_, _)当我们尝试不使用::Int时
我看到他们有不同的类型:
Prelude> let x = 1 + 1
Prelude> :t x
x :: Num a => a
Prelude> let x = 1 + 1 :: Int
Prelude> :t x
x :: Int但是为什么y的值依赖于它呢?
谢谢。
发布于 2014-07-25 19:12:46
当您指定x具有Num a => a类型时,编译器不可能知道在执行1 + 1时要使用哪个Num实例。相反,它所做的是使用默认。GHC为某些类型定义了默认类型,这样当无法确定使用哪种具体类型时,GHC仍然可以给出有意义的结果,而不会引发错误。所以当你看到
> 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。您甚至可以自己处理这个默认值:
> 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的这个功能,但是了解它是很好的。
https://stackoverflow.com/questions/24962582
复制相似问题