Haskell 可存储对象的异构列表
Haskell heterogeneous list of Storable objects
我想编写一个函数,可以找出可存储对象的异构列表(不同类型)
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes, ExistentialQuantification, ImpredicativeTypes #-}
pokeMany :: Ptr b -> Int -> [forall a. Storable a => a] -> IO ()
pokeMany _ _ [] = return ()
pokeMany ptr offset (x:xs) = do
pokeByteOff ptr offset x
pokeMany ptr (offset + sizeOf x) xs
somePoke :: Ptr a -> Int -> Int -> IO ()
somePoke ptr x1 x2 = pokeMany ptr 0 [x1, x2]
但是我遇到编译错误:
No instance for (Storable a1) arising from a use of `sizeOf'
The type variable `a1' is ambiguous
Note: there are several potential instances:
instance Storable CChar -- Defined in `Foreign.C.Types'
instance Storable CClock -- Defined in `Foreign.C.Types'
instance Storable CDouble -- Defined in `Foreign.C.Types'
Couldn't match expected type `a2' with actual type `Int'
`a2' is a rigid type variable bound by
a type expected by the context: Storable a2 => a2
和其他人...
然后我创建一些数据类型
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes, ExistentialQuantification, ImpredicativeTypes #-}
data AnyStorable = forall a. Storable a => AnyStorable a
pokeMany :: Ptr b -> Int -> [AnyStorable] -> IO ()
pokeMany _ _ [] = return ()
pokeMany ptr offset (AnyStorable x:xs) = do
pokeByteOff ptr offset x
pokeMany ptr (offset + sizeOf x) xs
somePoke :: Ptr a -> Int -> Int -> IO ()
somePoke ptr n c = pokeMany ptr 0 [AnyStorable n, AnyStorable c, AnyStorable 'a']
以上代码没有任何编译错误。
我可以编写 pokeMany
函数而不创建像 AnyStorable 这样的新数据类型吗?
简而言之,没有。您需要的是 exists
关键字来指定将映射到集合上的函数的签名。在数据类型中使用 forall
从另一面有效地表达了相同的意思。
顺便说一句,您可以考虑将 AnyStorable
作为 Storable
.
的实例
我想编写一个函数,可以找出可存储对象的异构列表(不同类型)
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes, ExistentialQuantification, ImpredicativeTypes #-}
pokeMany :: Ptr b -> Int -> [forall a. Storable a => a] -> IO ()
pokeMany _ _ [] = return ()
pokeMany ptr offset (x:xs) = do
pokeByteOff ptr offset x
pokeMany ptr (offset + sizeOf x) xs
somePoke :: Ptr a -> Int -> Int -> IO ()
somePoke ptr x1 x2 = pokeMany ptr 0 [x1, x2]
但是我遇到编译错误:
No instance for (Storable a1) arising from a use of `sizeOf'
The type variable `a1' is ambiguous
Note: there are several potential instances:
instance Storable CChar -- Defined in `Foreign.C.Types'
instance Storable CClock -- Defined in `Foreign.C.Types'
instance Storable CDouble -- Defined in `Foreign.C.Types'
Couldn't match expected type `a2' with actual type `Int'
`a2' is a rigid type variable bound by
a type expected by the context: Storable a2 => a2
和其他人...
然后我创建一些数据类型
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RankNTypes, ExistentialQuantification, ImpredicativeTypes #-}
data AnyStorable = forall a. Storable a => AnyStorable a
pokeMany :: Ptr b -> Int -> [AnyStorable] -> IO ()
pokeMany _ _ [] = return ()
pokeMany ptr offset (AnyStorable x:xs) = do
pokeByteOff ptr offset x
pokeMany ptr (offset + sizeOf x) xs
somePoke :: Ptr a -> Int -> Int -> IO ()
somePoke ptr n c = pokeMany ptr 0 [AnyStorable n, AnyStorable c, AnyStorable 'a']
以上代码没有任何编译错误。
我可以编写 pokeMany
函数而不创建像 AnyStorable 这样的新数据类型吗?
简而言之,没有。您需要的是 exists
关键字来指定将映射到集合上的函数的签名。在数据类型中使用 forall
从另一面有效地表达了相同的意思。
顺便说一句,您可以考虑将 AnyStorable
作为 Storable
.