我正在尝试为Vectors创建二进制实例。
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'
我一直试图通过这种方式进行推理并随机插入liftM
,但无济于事。
答案 0 :(得分:6)
您无法使用V.replicateM
填充Vector
吗?
vget :: (Binary a) => Get (V.Vector a)
vget = get >>= (`V.replicateM` get)
答案 1 :(得分:3)
问题在于您尝试撰写两个monad:ST
和Get
。
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
。您可以使用ST
变换器monad包,或者懒惰地将get monad中的一系列读取流式传输到ST构建器。