我遇到了一个奇怪的代码段,当用id
编写时,GHC无法正确地进行类型检查。我很确定这是一个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
。