我正在尝试为Foreign.Storable
找到Maybe
的实例。 Google从C2HS
instance Storable a => Storable (Maybe a) where
sizeOf _ = sizeOf (undefined :: Ptr ())
alignment _ = alignment (undefined :: Ptr ())
peek p = do
ptr <- peek (castPtr p)
if ptr == nullPtr
then return Nothing
else liftM Just $ peek ptr
poke p v = do
ptr <- case v of
Nothing -> return nullPtr
Just v' -> new v'
poke (castPtr p) ptr
还有a post关于它如何泄漏内存。是否存在其他地方的现有实例,或者是改进C2HS实例的方法?为什么Foreign.Storable
中没有一个实例开始?
答案 0 :(得分:3)
这是一个潜在的实例available on School of Haskell。我们的想法是存储一个包含0或1的额外字节,指示该值是否存在。
对于单个Storable
实例,肯定有更有效的方法。例如,Maybe Bool
可以存储在单个字节中而不是两个字节中。但我不认为你可以避免一般情况下的1字节开销。
这是我解决方案的主要部分:
instance Storable a => Storable (Maybe a) where
sizeOf x = sizeOf (stripMaybe x) + 1
alignment x = alignment (stripMaybe x)
peek ptr = do
filled <- peekByteOff ptr $ sizeOf $ stripMaybe $ stripPtr ptr
if filled == (1 :: Word8)
then do
x <- peek $ stripMaybePtr ptr
return $ Just x
else return Nothing
poke ptr Nothing = pokeByteOff ptr (sizeOf $ stripMaybe $ stripPtr ptr) (0 :: Word8)
poke ptr (Just a) = do
poke (stripMaybePtr ptr) a
pokeByteOff ptr (sizeOf a) (1 :: Word8)