可能重复:
runST 和函数组合
我遇到了一个奇怪的代码段,GHC 在使用id
. 我很确定这是一个 GHC 错误,但我想先在这里检查一下,然后再向 GHC 开发人员提交错误报告。我将从工作代码开始:
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
v :: V.Vector Int
v = V.create $ MV.replicate 1 0
这在 ST monad 中创建了一个新向量并且工作得很好:
>>> v
fromList [0]
当我编写时会出现该V.create
错误id
:
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
v :: V.Vector Int
v = id . V.create $ MV.replicate 1 0
...失败并出现以下错误:
Couldn't match expected type `forall s.
GHC.ST.ST s (MV.MVector s a0)'
with actual type `m0 (MV.MVector
(Control.Monad.Primitive.PrimState m0) a1)'
In the return type of a call of `MV.replicate'
In the second argument of `($)', namely `MV.replicate 1 0'
In the expression: id . V.create $ MV.replicate 1 0
但是,如果我应用id
而不是编写它,那么代码类型检查就好了:
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
v :: V.Vector Int
v = id $ V.create $ MV.replicate 1 0
基于此,我猜测与组合有关的某些事情id
会导致 GHC 意外泛化或专门化V.create
,从而导致它触发与 . 的类型不匹配MV.replicate
。但是,除此之外,我被卡住了,因为类型错误有点超出我的想象。
单态性限制也不是问题。即使我启用该NoMonomorphismRestriction
标志,问题仍然存在。
这是一个非常奇怪的问题,因为我期望id . f == f
. 此外,正确的身份法则也失败了,因为以下示例也无法进行类型检查:
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
v :: V.Vector Int
v = V.create . id $ MV.replicate 1 0
这是使用 GHC 版本 7.4.1 和vector-0.9.1
.