{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeOperators #-} ----------------------------------------------------------------------------- -- | -- Module : Generics.Regular.Functions.Binary -- Copyright : (c) 2009 Universiteit Utrecht -- License : BSD3 -- -- Maintainer : generics@haskell.org -- Stability : experimental -- Portability : non-portable -- -- Generic Data.Binary instances. -- -- These generic functions can be used to create a "Data.Binary" instance. For -- example, for a user-defined type @MyType@, the following code is necessary: -- -- > import Data.Binary -- > import Generics.Regular.Base -- > import Generics.Regular.Binary -- > -- > data MyType = ... -- > -- > $(deriveAll ''MyType "PFMyType") -- > type instance PF MyType = PFMyType -- > -- > instance Binary MyType where -- > put = gput -- > get = gget -- ----------------------------------------------------------------------------- module Generics.Regular.Functions.Binary ( -- * Binary put and get Binary, gput, gget ) where import Control.Applicative import Generics.Regular.Base import qualified Data.Binary as B -- * Generic Data.Binary instances. class Binary f where hput :: (r -> B.Put) -> f r -> B.Put hget :: ( B.Get r) -> B.Get (f r) instance Binary I where hput f (I x) = f x hget f = I <$> f instance B.Binary a => Binary (K a) where hput _ (K x) = B.put x hget _ = K <$> B.get instance Binary U where hput _ _ = B.put () hget _ = return U instance (Binary f, Binary g) => Binary (f :+: g) where hput t (L x) = B.put True >> hput t x hput t (R y) = B.put False >> hput t y hget t = B.get >>= \v -> if v then L <$> hget t else R <$> hget t instance (Binary f, Binary g) => Binary (f :*: g) where hput t (x :*: y) = hput t x >> hput t y hget t = (:*:) <$> hget t <*> hget t instance Binary f => Binary (C c f) where hput t (C x) = hput t x hget t = C <$> hget t instance Binary f => Binary (S s f) where hput t (S x) = hput t x hget t = S <$> hget t -- | Generic binary @put@ to be used with "Data.Binary.Put". gput :: (Regular a, Binary (PF a)) => a -> B.Put gput p = hput (\q -> gput q) (from p) -- | Generic binary @get@ to be used with "Data.Binary.Get". gget :: (Regular a, Binary (PF a)) => B.Get a gget = to <$> hget gget