From 34264aceedf3b44fb54a80232b511abec9800453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baldur=20Bl=C3=B6ndal?= Date: Wed, 23 Mar 2022 21:22:21 +0000 Subject: [PATCH 1/5] Binary instance for Generically. --- README.md | 36 +++++++++++++++++++++++++++--------- changelog.md | 6 ++++++ src/Data/Binary.hs | 33 +++++++++++++++++++++++---------- src/Data/Binary/Class.hs | 13 +++++++++++++ 4 files changed, 69 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 73bc9a55..0b2fa9ad 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The ``binary`` package provides Data.Binary, containing the Binary class, and associated methods, for serialising values to and from lazy -ByteStrings. +ByteStrings. A key feature of ``binary`` is that the interface is both pure, and efficient. The ``binary`` package is portable to GHC and Hugs. @@ -54,23 +54,41 @@ the ``Get`` and ``Put`` monads. More information in the haddock documentation. -## Deriving binary instances using GHC's Generic ## +## Deriving binary instances, ``Generically`` ## -Beginning with GHC 7.2, it is possible to use binary serialization without -writing any instance boilerplate code. +Beginning with GHC 9.4 it is possible to derive binary serialization +using the ``Generically`` newtype. + +This is achieved by deriving an instance of ``Generic`` and then +deriving the appropriate ``Binary T`` instance via ``Generically T``. ```haskell -{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} import Data.Binary -import GHC.Generics (Generic) +import GHC.Generics (Generic, Generically(..)) + +data Foo = Foo + deriving stock Generic + deriving Binary via Generically Foo +``` -data Foo = Foo deriving (Generic) +Beginning with GHC 7.2 this generic definition has been a part of the +``Binary`` typeclass. This could also be derived using the +``anyclass`` strategy: --- GHC will automatically fill out the instance -instance Binary Foo +```haskell +data Foo = Foo + deriving stock Generic + deriving anyclass Binary ``` +Which means the same as an empty class declaration: ``instance +Binary Foo``. + ## Contributors ## * Lennart Kolmodin diff --git a/changelog.md b/changelog.md index 96ea33bd..8626eb94 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,12 @@ binary binary-0.8.9.0 -------------- +- Add binary instance for 'GHC.Generics.Generically'. `Binary T` can + be derived via `Generically T` for a suitable generic type `T`. + +binary-0.8.9.0 +-------------- + - Compatibility with GHC 9.2 - Drop instances for deprecated `Data.Semigroup.Option` diff --git a/src/Data/Binary.hs b/src/Data/Binary.hs index 07970a3e..4e964f6c 100644 --- a/src/Data/Binary.hs +++ b/src/Data/Binary.hs @@ -230,19 +230,32 @@ decodeFileOrFail f = ------------------------------------------------------------------------ -- $generics -- --- Beginning with GHC 7.2, it is possible to use binary serialization --- without writing any instance boilerplate code. +-- Beginning with GHC 9.4 it is possible to derive binary +-- serialization using the 'GHC.Generics.Generically' newtype. -- --- > {-# LANGUAGE DeriveGeneric #-} +-- This is achieved by deriving an instance of 'GHC.Generics.Generic' +-- and then deriving the appropriate @'Binary' T@ instance via +-- @Generically T@. +-- +-- > {-# LANGUAGE DeriveAnyClass #-} +-- > {-# LANGUAGE DeriveGeneric #-} +-- > {-# LANGUAGE DerivingStrategies #-} +-- > {-# LANGUAGE DerivingVia #-} -- > -- > import Data.Binary --- > import GHC.Generics (Generic) +-- > import GHC.Generics (Generic, Generically(..)) -- > -- > data Foo = Foo --- > deriving (Generic) --- > --- > -- GHC will automatically fill out the instance --- > instance Binary Foo +-- > deriving stock Generic +-- > deriving Binary via Generically Foo -- --- This mechanism makes use of GHC's efficient built-in generics --- support. +-- Beginning with GHC 7.2 this generic definition has been a part of +-- the 'Binary' typeclass. This could also be derived using the +-- @anyclass@ strategy: +-- +-- > data Foo = Foo +-- > deriving stock Generic +-- > deriving anyclass Binary +-- +-- Which means the same as an empty class declaration: @instance +-- Binary Foo@. diff --git a/src/Data/Binary/Class.hs b/src/Data/Binary/Class.hs index 895f43ba..21bf6545 100644 --- a/src/Data/Binary/Class.hs +++ b/src/Data/Binary/Class.hs @@ -13,6 +13,10 @@ #define HAS_TYPELITS_CHAR #endif +#if MIN_VERSION_base(4,17,0) +#define HAS_GENERICALLY +#endif + #if MIN_VERSION_base(4,8,0) #define HAS_NATURAL #define HAS_VOID @@ -175,6 +179,15 @@ class Binary t where defaultPutList :: Binary a => [a] -> Put defaultPutList xs = put (length xs) <> mapM_ put xs +#ifdef HAS_GENERICALLY +instance (Generic a, GBinaryPut (Rep a), GBinaryGet (Rep a)) => Binary (Generically a) where + put :: Generically a -> Put + put (Generically a) = gput (from a) + + get :: Get (Generically a) + get = Generically . to <$> gget +#endif + ------------------------------------------------------------------------ -- Simple instances From f7d6f13add742dac7c6dd166491b6f174797c616 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Mon, 6 Mar 2023 17:13:14 -0500 Subject: [PATCH 2/5] Update changelog.md --- changelog.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index a2f3e50e..6703e00d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,16 +1,17 @@ binary ====== -binary-0.8.9.1 + +binary-0.8.9.2 -------------- -- Fix redundant pattern match warning in GHC 9.4 +- Add binary instance for `GHC.Generics.Generically`. `Binary T` can + be derived via `Generically T` for a suitable generic type `T`. -binary-0.8.9.0 +binary-0.8.9.1 -------------- -- Add binary instance for 'GHC.Generics.Generically'. `Binary T` can - be derived via `Generically T` for a suitable generic type `T`. +- Fix redundant pattern match warning in GHC 9.4 binary-0.8.9.0 -------------- From fc4f9bfaacb3579bac407a30ab11a69d6e73b0c7 Mon Sep 17 00:00:00 2001 From: konsumlamm <44230978+konsumlamm@users.noreply.github.com> Date: Sun, 12 Apr 2026 18:39:49 +0200 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> --- README.md | 3 +-- src/Data/Binary.hs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index aa9e6f3a..eece40c8 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,6 @@ This is achieved by deriving an instance of ``Generic`` and then deriving the appropriate ``Binary T`` instance via ``Generically T``. ```haskell -{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE DerivingVia #-} @@ -77,7 +76,7 @@ data Foo = Foo deriving Binary via Generically Foo ``` -Beginning with GHC 7.2 this generic definition has been a part of the +Beginning with GHC 7.2, a generic definition has been a part of the ``Binary`` typeclass. This could also be derived using the ``anyclass`` strategy: diff --git a/src/Data/Binary.hs b/src/Data/Binary.hs index 4e964f6c..c719db9f 100644 --- a/src/Data/Binary.hs +++ b/src/Data/Binary.hs @@ -237,7 +237,6 @@ decodeFileOrFail f = -- and then deriving the appropriate @'Binary' T@ instance via -- @Generically T@. -- --- > {-# LANGUAGE DeriveAnyClass #-} -- > {-# LANGUAGE DeriveGeneric #-} -- > {-# LANGUAGE DerivingStrategies #-} -- > {-# LANGUAGE DerivingVia #-} @@ -249,7 +248,7 @@ decodeFileOrFail f = -- > deriving stock Generic -- > deriving Binary via Generically Foo -- --- Beginning with GHC 7.2 this generic definition has been a part of +-- Beginning with GHC 7.2, a generic definition has been a part of -- the 'Binary' typeclass. This could also be derived using the -- @anyclass@ strategy: -- From 3961d72a37eaf68ea2f3653d4993d81fda80abf7 Mon Sep 17 00:00:00 2001 From: konsumlamm <44230978+konsumlamm@users.noreply.github.com> Date: Sun, 12 Apr 2026 19:26:33 +0200 Subject: [PATCH 4/5] Enable UndecidableInstances --- src/Data/Binary/Class.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Binary/Class.hs b/src/Data/Binary/Class.hs index a32b6c7a..2592c3f9 100644 --- a/src/Data/Binary/Class.hs +++ b/src/Data/Binary/Class.hs @@ -4,6 +4,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE PolyKinds #-} +{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE Trustworthy #-} #if MIN_VERSION_base(4,16,0) From 96d5f718b20f22a02498714405c5fce121b46d4d Mon Sep 17 00:00:00 2001 From: konsumlamm <44230978+konsumlamm@users.noreply.github.com> Date: Sun, 12 Apr 2026 19:29:55 +0200 Subject: [PATCH 5/5] Enable InstanceSigs --- src/Data/Binary/Class.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Data/Binary/Class.hs b/src/Data/Binary/Class.hs index 2592c3f9..2ad3a461 100644 --- a/src/Data/Binary/Class.hs +++ b/src/Data/Binary/Class.hs @@ -1,6 +1,7 @@ {-# LANGUAGE CPP, FlexibleContexts #-} {-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE GADTs #-} +{-# LANGUAGE InstanceSigs #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE PolyKinds #-}