Haskell可存储对象的异构列表

时间:2016-07-08 05:52:11

标签: haskell polymorphism existential-type heterogeneous

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

Compile Error: AppBundle\Components\Factory::getDBO(): Failed opening required '/foo/bar' (include_path='.:')

但我收到编译错误:

{-# 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

上面的代码没有任何编译错误。

我可以在不创建像AnyStorable这样的新数据类型的情况下编写{-# 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'] 函数吗?

1 个答案:

答案 0 :(得分:1)

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

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