Haskell 如何打印可变向量
Haskell how to print mutable vector
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Primitive
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
fromList :: [a] -> IO (MV.IOVector a)
fromList = V.thaw . V.fromList
printMV :: PrimMonad m => MV.MVector (PrimState m) a -> m ()
printMV = liftIO . print . V.freeze
我想打印 MVector
(很惊讶没有显示实例)。所以我得先freez
吧Vector
。
然后我得到了类型错误:
Algo/QuickSort.hs:12:11: error: …
• Couldn't match type ‘PrimState m’ with ‘PrimState m0’
Expected type: MV.MVector (PrimState m) a -> m ()
Actual type: MV.MVector (PrimState m0) a -> m ()
NB: ‘PrimState’ is a non-injective type family
The type variable ‘m0’ is ambiguous
• In the expression: liftIO . print . V.freeze
In an equation for ‘printMV’: printMV = liftIO . print . V.freeze
• Relevant bindings include
printMV :: MV.MVector (PrimState m) a -> m ()
(bound at /home/skell/btree/Algo/QuickSort.hs:12:1)
|
Compilation failed.
我也试过 IOVector
printMV :: MV.IOVector a -> IO ()
printMV = liftIO . print . V.freeze
这次错误不一样:
Algo/QuickSort.hs:12:28: error: …
• Couldn't match type ‘PrimState m0’ with ‘RealWorld’
Expected type: MV.IOVector a -> m0 (V.Vector a)
Actual type: MV.MVector (PrimState m0) a -> m0 (V.Vector a)
The type variable ‘m0’ is ambiguous
• In the second argument of ‘(.)’, namely ‘V.freeze’
In the second argument of ‘(.)’, namely ‘print . V.freeze’
In the expression: liftIO . print . V.freeze
|
Compilation failed.
发生了几件事 - 第一个解决方案:
printMV :: MonadIO m => Show a => PrimMonad m => MV.MVector (PrimState m) a -> m ()
printMV v = do
fv <- V.freeze v
liftIO $ print fv
所以问题:
freeze
是一个 m
-action 本身所以它需要被绑定
liftIO
需要一个 MonadIO
实例
- 为了使
Vector a
成为 Show
- a
也必须在那个 class 中
你的第二个版本类似:
printMV2 :: Show a => MV.IOVector a -> IO ()
printMV2 v = V.freeze v >>= print
- 需要
Show
实例用于 a
- 需要
>>=
V.freeze
的结果(与上面相同 - do
隐式执行此操作)
- 这里不需要
liftIO
因为你已经在其中了
import Control.Monad.IO.Class (liftIO)
import Control.Monad.Primitive
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV
fromList :: [a] -> IO (MV.IOVector a)
fromList = V.thaw . V.fromList
printMV :: PrimMonad m => MV.MVector (PrimState m) a -> m ()
printMV = liftIO . print . V.freeze
我想打印 MVector
(很惊讶没有显示实例)。所以我得先freez
吧Vector
。
然后我得到了类型错误:
Algo/QuickSort.hs:12:11: error: …
• Couldn't match type ‘PrimState m’ with ‘PrimState m0’
Expected type: MV.MVector (PrimState m) a -> m ()
Actual type: MV.MVector (PrimState m0) a -> m ()
NB: ‘PrimState’ is a non-injective type family
The type variable ‘m0’ is ambiguous
• In the expression: liftIO . print . V.freeze
In an equation for ‘printMV’: printMV = liftIO . print . V.freeze
• Relevant bindings include
printMV :: MV.MVector (PrimState m) a -> m ()
(bound at /home/skell/btree/Algo/QuickSort.hs:12:1)
|
Compilation failed.
我也试过 IOVector
printMV :: MV.IOVector a -> IO ()
printMV = liftIO . print . V.freeze
这次错误不一样:
Algo/QuickSort.hs:12:28: error: …
• Couldn't match type ‘PrimState m0’ with ‘RealWorld’
Expected type: MV.IOVector a -> m0 (V.Vector a)
Actual type: MV.MVector (PrimState m0) a -> m0 (V.Vector a)
The type variable ‘m0’ is ambiguous
• In the second argument of ‘(.)’, namely ‘V.freeze’
In the second argument of ‘(.)’, namely ‘print . V.freeze’
In the expression: liftIO . print . V.freeze
|
Compilation failed.
发生了几件事 - 第一个解决方案:
printMV :: MonadIO m => Show a => PrimMonad m => MV.MVector (PrimState m) a -> m ()
printMV v = do
fv <- V.freeze v
liftIO $ print fv
所以问题:
freeze
是一个m
-action 本身所以它需要被绑定liftIO
需要一个MonadIO
实例- 为了使
Vector a
成为Show
-a
也必须在那个 class 中
你的第二个版本类似:
printMV2 :: Show a => MV.IOVector a -> IO ()
printMV2 v = V.freeze v >>= print
- 需要
Show
实例用于a
- 需要
>>=
V.freeze
的结果(与上面相同 -do
隐式执行此操作) - 这里不需要
liftIO
因为你已经在其中了