{-# LANGUAGE TypeOperators, FlexibleContexts, UndecidableInstances #-} module Data.Binary.DerivingVia ( Alternatively(..) ) where import Control.Applicative import Data.Binary import GHC.Generics newtype Alternatively a = Alternatively { getAlt :: a } class GAltBinary grecord where gAltGet :: Get (grecord p) gAltPut :: grecord p -> Put instance Binary grecord => GAltBinary (K1 i grecord) where gAltGet = K1 <$> get gAltPut = put . unK1 instance GAltBinary grecord => GAltBinary (M1 i t grecord) where gAltGet = M1 <$> gAltGet gAltPut = gAltPut . unM1 instance (GAltBinary l, GAltBinary r) => GAltBinary (l :*: r) where gAltGet = (:*:) <$> gAltGet <*> gAltGet gAltPut (l :*: r) = gAltPut l <> gAltPut r instance (GAltBinary l, GAltBinary r) => GAltBinary (l :+: r) where gAltGet = L1 <$> gAltGet <|> R1 <$> gAltGet gAltPut (L1 l) = gAltPut l gAltPut (R1 r) = gAltPut r instance (Generic a, GAltBinary (Rep a)) => Binary (Alternatively a) where get = Alternatively . to <$> gAltGet put = gAltPut . from . getAlt