Skip to content

NFData(1) instances of Generically(1). #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 65 additions & 30 deletions Control/DeepSeq.hs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE UndecidableInstances #-}

#if __GLASGOW_HASKELL__ >= 811 && __GLASGOW_HASKELL__ < 901
-- For the Option instance (https://gitlab.haskell.org/ghc/ghc/issues/15028)
Expand All @@ -19,6 +21,10 @@
-- At the moment of writing GHC source tree has not yet bumped `base` version,
-- so using __GLASGOW_HASKELL__ as a proxy instead of MIN_VERSION_base(4,17,0).

#if MIN_VERSION_base(4,17,0)
#define HAS_GENERICALLY
#endif

-----------------------------------------------------------------------------
-- |
-- Module : Control.DeepSeq
Expand Down Expand Up @@ -260,7 +266,7 @@ f $!! x = x `deepseq` f x
-- > evaluate . force =<< hGetContents h
--
-- @since 1.2.0.0
force :: (NFData a) => a -> a
force :: NFData a => a -> a
force x = x `deepseq` x

-- | Deeply strict version of 'Control.Applicative.<$>'.
Expand Down Expand Up @@ -302,41 +308,41 @@ class NFData a where
--
-- === 'Generic' 'NFData' deriving
--
-- Starting with GHC 7.2, you can automatically derive instances
-- for types possessing a 'Generic' instance.
-- It is possible to derive an instance of 'NFData' for a type @T@
-- possessing a 'Generic' instance via @'GHC.Generics.Generically'
-- T@ (since GHC 9.4).
--
-- Note: 'Generic1' can be auto-derived starting with GHC 7.4
--
-- > {-# LANGUAGE DeriveGeneric #-}
-- > {-# LANGUAGE DeriveAnyClass #-}
-- > {-# LANGUAGE DeriveGeneric #-}
-- > {-# LANGUAGE DerivingStrategies #-}
-- > {-# LANGUAGE DerivingVia #-}
-- >
-- > import GHC.Generics (Generic, Generic1)
-- > import GHC.Generics (Generic, Generic1, Generically(..), Generically1(..))
-- > import Control.DeepSeq
-- >
-- > data Foo a = Foo a String
-- > deriving (Eq, Generic, Generic1)
-- >
-- > instance NFData a => NFData (Foo a)
-- > instance NFData1 Foo
-- > deriving stock (Eq, Generic, Generic1)
-- > deriving NFData via Generically (Foo a)
-- > deriving NFData1 via Generically1 Foo
-- >
-- > data Colour = Red | Green | Blue
-- > deriving Generic
-- >
-- > instance NFData Colour
-- > deriving stock Generic
-- > deriving NFData via Generically Colour
--
-- Starting with GHC 7.10, the example above can be written more
-- concisely by enabling the new @DeriveAnyClass@ extension:
-- It had been possible to derive it with the @DerivingAnyClass@
-- since GHC 7.10 (although at that point the @anyclass@ deriving
-- strategy could not be named).
--
-- > {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
-- >
-- > import GHC.Generics (Generic)
-- > import Control.DeepSeq
-- >
-- > data Foo a = Foo a String
-- > deriving (Eq, Generic, Generic1, NFData, NFData1)
-- >
-- > data Colour = Red | Green | Blue
-- > deriving (Generic, NFData)
-- >
-- > deriving anyclass (NFData, NFData1)
-- > deriving anyclass NFData
--
-- @DerivingAnyClass@ is equivalent to writing an empty instance
-- instance declaration which relies on generic default methods
-- (available since GHC 7.2).
--
-- > instance NFData (Foo a)
-- > instance NFData1 Foo
-- > instance NFData Colour
--
-- === Compatibility with previous @deepseq@ versions
--
Expand Down Expand Up @@ -367,20 +373,49 @@ class NFData a where
default rnf :: (Generic a, GNFData Zero (Rep a)) => a -> ()
rnf = grnf RnfArgs0 . from

#ifdef HAS_GENERICALLY
instance (Generic a, GNFData Zero (Rep a)) => NFData (Generically a) where
rnf :: Generically a -> ()
rnf (Generically a) = grnf RnfArgs0 (from a)
#endif

-- | A class of functors that can be fully evaluated.
--
-- It is possible to derive an instance of 'NFData1' for a type
-- constructor @F@ possessing a 'Generic1' instance via
-- @'GHC.Generics.Generically1' F@ (since GHC 9.4).
--
-- > {-# LANGUAGE DeriveAnyClass #-}
-- > {-# LANGUAGE DeriveGeneric #-}
-- > {-# LANGUAGE DerivingStrategies #-}
-- > {-# LANGUAGE DerivingVia #-}
-- >
-- > import GHC.Generics (Generic, Generic1, Generically(..), Generically1(..))
-- > import Control.DeepSeq
-- >
-- > data Foo a = Foo a String
-- > deriving stock (Eq, Generic, Generic1)
-- > deriving NFData via Generically (Foo a)
-- > deriving NFData1 via Generically1 Foo
--
-- @since 1.4.3.0
class NFData1 f where
-- | 'liftRnf' should reduce its argument to normal form (that is, fully
-- evaluate all sub-components), given an argument to reduce @a@ arguments,
-- and then return '()'.
--
-- See 'rnf' for the generic deriving.
-- See 'rnf' for more information on generic deriving.
liftRnf :: (a -> ()) -> f a -> ()

default liftRnf :: (Generic1 f, GNFData One (Rep1 f)) => (a -> ()) -> f a -> ()
liftRnf r = grnf (RnfArgs1 r) . from1

#ifdef HAS_GENERICALLY
instance (Generic1 f, GNFData One (Rep1 f)) => NFData1 (Generically1 f) where
liftRnf :: (a -> ()) -> (Generically1 f a -> ())
liftRnf r (Generically1 as) = grnf (RnfArgs1 r) (from1 as)
#endif

-- | Lift the standard 'rnf' function through the type constructor.
--
-- @since 1.4.3.0
Expand Down
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog for [`deepseq` package](http://hackage.haskell.org/package/deepseq)

## 1.4.??

* Add instances for `Generically` and `Generically1`. `NFData A`
can now be derived via `Generically A` for `Generic A`.
`NFData1 F` can be derived via `Generically1 F` for `Generic1 F`.

## 1.4.7.0

* Add instances for `Solo` (GHC-9)
Expand Down