1

我正在尝试为向量编写二进制实例。

import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
import Data.Binary


instance (Binary a) => Binary (V.Vector a) where
    put = vput
    get = vget

实现方式是:先输出长度,再输出所有数据点

vput v = (put (V.length v)) >> (put `V.mapM_` v)

问题出在vget. 我想使用V.create(我计划输出非常大的向量,语义看起来非常合适。

这是我的尝试:

vget :: (Binary a) => Get (V.Vector a)
vget = do
    size <- get
    vec <- liftM V.create $ do
        v <- (liftM MV.new) size
        forM_ [0..(size-1)] $ \i -> do
            val <- get
            (liftM3 MV.write) v i val
        return v -- This is line 22
    return vec

错误是

SerializeVector.hs:22:16:
    Couldn't match expected type `forall s. ST s (MV.MVector s a0)'
            with actual type `Get a10'

我一直试图通过推理并随机插入liftMs,但无济于事。

4

2 回答 2

6

不能V.replicateM用来填Vector吗?

vget :: (Binary a) => Get (V.Vector a)
vget = get >>= (`V.replicateM` get)
于 2012-05-07T18:44:42.753 回答
3

这里的问题是您正在尝试编写两个 monad:STGet.

   vec <- liftM V.create $ do
        v <- (liftM MV.new) size
        forM_ [0..(size-1)] $ \i -> do
            val <- get                -- run an action in the `Get` monad
            (liftM3 MV.write) v i val -- write it in the `ST` monad

这是不可能的。您需要一个ST转换器来允许您get从您的ST操作中运行调用。您可能可以使用STtransformer monad 包,或者将来自get monad 的一系列读取延迟流式传输到ST 构建器中。

于 2012-05-07T17:47:51.770 回答