diff --git a/src/Data/Binary.hs b/src/Data/Binary.hs index 07970a3e..44f700bb 100644 --- a/src/Data/Binary.hs +++ b/src/Data/Binary.hs @@ -49,6 +49,8 @@ module Data.Binary ( , GBinaryGet(..) , GBinaryPut(..) + , GenericBinary(..) + -- * The Get and Put monads , Get , Put diff --git a/src/Data/Binary/Class.hs b/src/Data/Binary/Class.hs index a3d3878c..f808e703 100644 --- a/src/Data/Binary/Class.hs +++ b/src/Data/Binary/Class.hs @@ -4,6 +4,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE Trustworthy #-} +{-# LANGUAGE UndecidableInstances #-} #if __GLASGOW_HASKELL__ >= 706 {-# LANGUAGE PolyKinds #-} @@ -41,6 +42,8 @@ module Data.Binary.Class ( , GBinaryGet(..) , GBinaryPut(..) + , GenericBinary(..) + ) where import Data.Word @@ -1045,3 +1048,33 @@ instance Binary SomeTypeRep where get = getSomeTypeRep #endif + +------------------------------------------------------------------------ +-- Wrapper for DerivingVia + +-- | 'GenericBinary' can be used in conjunction with DerivingVia. It is most useful when chaining +-- types that augment derived instances. +-- +-- Simple usage with DerivingVia: +-- +-- @ +-- data Foo = Foo Int String +-- deriving Generic +-- deriving Binary via GenericBinary Foo +-- @ +-- +-- When chaining multiple augmentations: +-- +-- @ +-- data Foo = Foo Int String +-- deriving Generic +-- deriving Binary via Augmentation1 (Augmentation2 (GenericBinary Foo)) +-- @ +-- +newtype GenericBinary a = GenericBinary + { unGenericBinary :: a } + +instance (Generic a, GBinaryPut (Rep a), GBinaryGet (Rep a)) => Binary (GenericBinary a) where + put = gput . from . unGenericBinary + + get = fmap (GenericBinary . to) gget