【问题标题】:Haskell heterogeneous list of Storable objectsHaskell 可存储对象的异构列表
【发布时间】:2016-07-08 05:52:11
【问题描述】:

我想写一个函数,可以戳出可存储对象(不同类型)的异构列表

{-# 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 这样的新数据类型吗?

【问题讨论】:

    标签: haskell polymorphism existential-type heterogeneous


    【解决方案1】:

    简而言之,没有。您需要的是 exists 关键字来指定将映射到集合上的函数的签名。在数据类型中使用forall 可以有效地从另一端表达相同的意思。

    顺便说一句,您可以考虑将AnyStorable 设为Storable 的实例。

    【讨论】:

    • 当然,你是对的。 AnyStorable 必须是 Storable 的实例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-18
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 2011-06-03
    • 2018-06-15
    相关资源
    最近更新 更多