import Data.Typeable (Typeable, typeOf)
import qualified Data.Vector.Storable as VS
import Data.Word (Word8)
import Foreign.Ptr (Ptr, castPtr)
import Foreign.Storable (Storable, alignment, peek,
peekByteOff, poke, pokeByteOff,
sizeOf)
import Test.Hspec (Spec, hspec, shouldBe)
import Test.Hspec.QuickCheck (prop)
import Test.QuickCheck.Arbitrary (Arbitrary)
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)
stripMaybe :: Maybe a -> a
stripMaybe _ = error "stripMaybe"
stripMaybePtr :: Ptr (Maybe a) -> Ptr a
stripMaybePtr = castPtr
stripPtr :: Ptr a -> a
stripPtr _ = error "stripPtr"
test :: (Arbitrary a, Typeable a, Show a, Storable a, Eq a) => a -> Spec
test dummy = prop (show $ typeOf dummy) $ \vals ->
let v = VS.fromList vals `asTypeOf` VS.singleton (Just dummy)
in VS.toList v `shouldBe` vals
main :: IO ()
main = hspec $ do
test (undefined :: Int)
test (undefined :: Char)
test (undefined :: Double)
test (undefined :: Bool)
Storable instance of Maybe
As of March 2020, School of Haskell has been switched to read-only mode.
comments powered by Disqus