forall a . (Fractional a) => a
是函数类型。
(a :: *)
以及类型为
Fractional a
. 每当你看到
=>
,它在操作上是一个函数,并在GHC的核心表示中编译为一个函数,有时也在机器代码中保留一个函数。主要区别在于
->
和
=>
后者的参数不能由程序员显式给出,并且总是通过实例解析隐式填充。
step
第一:
step :: State -> State
step (State f) =
let vs = trace "hello" f
in State (vs `seq` f)
在这里,
vs
Fractional
默认为
Double
. 如果你打开
-Wtype-defaults
警告,GHC会向你指出这一点。自从
vs :: Double
,它只是一个数值,由返回的
关闭
. 正确的,
vs `seq` f
给a。(小数a)=>a
对
f
.
所以,每个人
步
创建一个新的函数闭包,它捕获
vs::双精度
. 如果我们打电话
步
三次,我们得到三个闭包和三个
在里面,每个闭包都引用上一个闭包。然后,当我们写
vstate (step $ step $ step initState)
,我们再次默认为
双倍
Fractional Double
实例。所有的
对
-es调用前面的闭包
,但是
对
只计算一次,因为它们通常很懒
不重新计算的值。
但是,如果我们能够
NoMonomorphismRestriction
,
对
一般化为
forall a. Fractional a => a
现在,慢点
步
:
step :: State -> State
step (State f) = State ((trace "hello" f) `seq` f)
指数
在步骤数中调用的次数,因为
step f
电话
两次,如果没有优化,则不会共享计算,因为这两个调用都发生在lambda下。在
(trace "hello" f) `seq` f
,第一个呼叫
f型
默认为
分数倍
,而第二个调用只是通过隐式
像以前一样。
如果我们打开优化,GHC会发现
调用不依赖于函数参数,并浮起
trace "hello" f
到let绑定,生成的代码与快速版本中的代码几乎相同。