以下代码在GHC-7.8.3上编译,但我无法弄清楚如何为f
编写显式类型签名:
import qualified Data.Vector.Generic.Mutable
import Data.Vector.Generic (freeze, thaw, Mutable, Vector)
import Control.Monad.Primitive (PrimState, PrimMonad)
import Control.Monad.ST (runST, ST)
f v = Data.Vector.Generic.Mutable.read v 0 >>=
Data.Vector.Generic.Mutable.write v 0 >>
return v
g :: Vector v a => v a -> v a
g v = runST $ (thaw v) >>= f >>= freeze
main = return ()
f
这里只是一个函数,它对可变向量进行一些工作并返回一个可变向量。我做了一个虚拟read
和write
只是为了强制这个类型是一个向量。
那么如何为f
编写类型签名?
注意:我进行了大量编辑,并提出了澄清和简化的问题。
答案 0 :(得分:2)
f
的那种类型并不真正有意义,正是因为类型族是非内射的(这正是它告诉你的)。您说f
需要Mutable v (PrimState m) a
,但这无法确定v
实际上是什么 - 这就是非内射的含义。然后,输出必须依赖于v
。但你又不知道v
是什么。
在这种情况下,解决方案很明显:给f
类型Monad m => a -> m a
。但一般来说,你必须以某种方式将类型v
传递给函数。通常你会写
f :: (PrimMonad m, Vector v a)
=> proxy v -> Mutable v (PrimState m) a -> m (Mutable v (PrimState m) a)
f _ = return
推断类型
f v = read v 0 >>=
write v 0 >>
return v
是
(MVector v a, PrimMonad m) => v (PrimState m) a -> m (v (PrimState m) a)
函数的参数不是类型族应用程序。这正是你应该给它的显式类型。类型v
是已知的。如果你试图给它类型
(PrimMonad m, Vector v a) => Mutable v (PrimState m) a -> m (Mutable v (PrimState m) a)
像以前一样,你得到完全相同的错误。