This question already has an answer here:
:sprint for polymorphic values?
(1个答案)
去年关闭。
我试图弄清懒惰的评估是如何工作的,我尝试如下:
问题是,为什么最后一行不显示评估列表?我之前评估过一条线。
编辑
并肩希望它将更加明显:
编辑2:在我看来,REPL中的单态性限制或缺乏这种限制可能会引起一些混乱。在已编译的代码中,let语句中的值将采用单个具体类型,而不是多态的,因此根本没有此“问题”:
(1个答案)
去年关闭。
我试图弄清懒惰的评估是如何工作的,我尝试如下:
Prelude> a = [1,2,3,5,6]
Prelude> b = map (\x -> x * 8) a
Prelude> :sprint b
b = _
Prelude> b
[8,16,24,40,48]
Prelude> :sprint b
b = _
问题是,为什么最后一行不显示评估列表?我之前评估过一条线。
最佳答案
因为对于某些b
,Num a
基本上是从[a]
字典到a
的函数。如果这是具体类型,则将与您预期的一样:
let a Prelude> let a = [1..4] :: [Int]
Prelude> let b = map (*8) a
Prelude> :sprint b
b = _
Prelude> b
[8,16,24,32]
Prelude> :sprint b
b = [8,16,24,32]
编辑
并肩希望它将更加明显:
Prelude> let a = [1..4]
Prelude> :t a
a :: (Num a, Enum a) => [a]
Prelude> let poly_b = map (*8) a
Prelude> let concrete_b = map (* (8 ::Int)) a
Prelude> :sprint poly_b
poly_b = _
Prelude> :sprint concrete_b
concrete_b = _
Prelude> poly_b
[8,16,24,32]
Prelude> concrete_b
[8,16,24,32]
Prelude> :sprint poly_b
poly_b = _
Prelude> :sprint concrete_b
concrete_b = [8,16,24,32]
编辑2:在我看来,REPL中的单态性限制或缺乏这种限制可能会引起一些混乱。在已编译的代码中,let语句中的值将采用单个具体类型,而不是多态的,因此根本没有此“问题”:
Prelude> :set -XMonomorphismRestriction
Prelude> let a = [1..4]
Prelude> let b = map (*8) a
Prelude> :sprint b
b = _
Prelude> b
[8,16,24,32]
Prelude> :sprint b
b = [8,16,24,32]