3

可能重复:
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.

4

0 回答 0