storable-record-0.0.3.1: Elegant definition of Storable instances for records

Safe Haskell | Safe
Language | Haskell98

Foreign.Storable.Record

Description

Here we show an example of how to define a Storable instance with this module.

    import Foreign.Storable.Record as Store
    import Foreign.Storable (Storable (..), )

    import Control.Applicative (liftA2, )

    data Stereo a = Stereo {left, right :: a}

    store :: Storable a => Store.Dictionary (Stereo a)
    store =
       Store.run $
       liftA2 Stereo
          (Store.element left)
          (Store.element right)

    instance (Storable a) => Storable (Stereo a) where
       sizeOf = Store.sizeOf store
       alignment = Store.alignment store
       peek = Store.peek store
       poke = Store.poke store

The `Stereo` constructor is exclusively used for constructing the `peek` function, whereas the accessors in the `element` calls are used for assembling the `poke` function. It is required that the order of arguments of `Stereo` matches the record accessors in the `element` calls. If you want that the stored data correctly and fully represents your Haskell data, it must hold:

      Stereo (left x) (right x) = x   .

Unfortunately this cannot be checked automatically. However, mismatching types that are caused by swapped arguments are detected by the type system. Our system performs for you: Size and alignment computation, poking and peeking. Thus several inconsistency bugs can be prevented using this package, like size mismatching the space required by `poke` actions. There is no more restriction, thus smart constructors and accessors and nested records work, too. For nested records however, I recommend individual Storable instances for the sub-records.

You see it would simplify class instantiation if we could tell the class dictionary at once instead of defining each method separately.

In this implementation we tail pad records according to the overall required alignment in conformance to the Linux/X86 ABI.

# Documentation

data Dictionary r Source #

data Access r a Source #

Instances

Functor (Access r) Source # |
Methods fmap :: (a -> b) -> Access r a -> Access r b # (<$) :: a -> Access r b -> Access r a #
Applicative (Access r) Source # |
Methods pure :: a -> Access r a # (<*>) :: Access r (a -> b) -> Access r a -> Access r b # (*>) :: Access r a -> Access r b -> Access r b # (<*) :: Access r a -> Access r b -> Access r a #

element :: Storable a => (r -> a) -> Access r a Source #

run :: Access r r -> Dictionary r Source #

alignment :: Dictionary r -> r -> Int Source #

sizeOf :: Dictionary r -> r -> Int Source #

peek :: Dictionary r -> Ptr r -> IO r Source #

poke :: Dictionary r -> Ptr r -> r -> IO () Source #