如何为Data.Vector编写类型签名

时间:2015-01-15 17:46:50

标签: haskell types

以下代码在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这里只是一个函数,它对可变向量进行一些工作并返回一个可变向量。我做了一个虚拟readwrite只是为了强制这个类型是一个向量。

那么如何为f编写类型签名?

注意:我进行了大量编辑,并提出了澄清和简化的问题。

1 个答案:

答案 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)
像以前一样,你得到完全相同的错误。