packages feed

HarmTrace-1.0: src/HarmTrace/HAnTree/Binary.hs

{-# LANGUAGE GADTs                    #-}
{-# LANGUAGE FlexibleInstances        #-}
{-# LANGUAGE FlexibleContexts         #-}
{-# LANGUAGE TypeOperators            #-}

-- Generic Binary

module HarmTrace.HAnTree.Binary where

import Control.Monad (liftM, liftM2)
import Data.Binary
import Generics.Instant


class GBinary a where
  gput :: a -> Put
  gget :: Get a


instance GBinary U where
  gput _ = return ()
  gget = return U

instance (GBinary a) => GBinary (CEq c p p a) where
  gput (C a) = gput a
  gget = liftM C gget
{-
instance (GBinary a) => GBinary (CEq c p q a) where
  gput _ = return ()
  gget = error "gget: CEq impossible"
-}
instance (GBinary a, GBinary b) => GBinary (a :+: b) where
  gput (L a) = put (0 :: Word8) >> gput a
  gput (R a) = put (1 :: Word8) >> gput a
  gget = do t <- get :: Get Word8
            case t of
              0 -> liftM L gget
              1 -> liftM R gget
              _ -> error "gget: :+: impossible"

instance (GBinary a, GBinary b) => GBinary (a :*: b) where
  gput (a :*: b) = gput a >> gput b
  gget = liftM2 (:*:) gget gget

instance (Binary a) => GBinary (Rec a) where
  gput (Rec a) = put a
  gget = liftM Rec get

instance (Binary a) => GBinary (Var a) where
  gput (Var a) = put a
  gget = liftM Var get


-- Default implementations
getDefault :: (Representable a, GBinary (Rep a)) => Get a
getDefault = fmap to gget

putDefault :: (Representable a, GBinary (Rep a)) => a -> Put
putDefault = gput . from