-
Notifications
You must be signed in to change notification settings - Fork 29
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
Add rnfFoldableLTR and rnfFoldableRTL #18
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,16 +5,24 @@ | |
{-# LANGUAGE FlexibleContexts #-} | ||
{-# LANGUAGE TypeOperators #-} | ||
# if MIN_VERSION_array(0,4,0) | ||
#if __GLASGOW_HASKELL__ >= 708 | ||
-- We can't use Safe because Data.Coerce is not marked safe. | ||
{-# LANGUAGE Trustworthy #-} | ||
#else | ||
{-# LANGUAGE Safe #-} | ||
#endif | ||
# endif | ||
#endif | ||
#if __GLASGOW_HASKELL__ >= 706 | ||
{-# LANGUAGE PolyKinds #-} | ||
#endif | ||
#if __GLASGOW_HASKELL__ >= 708 | ||
{-# LANGUAGE ScopedTypeVariables #-} | ||
#endif | ||
----------------------------------------------------------------------------- | ||
-- | | ||
-- Module : Control.DeepSeq | ||
-- Copyright : (c) The University of Glasgow 2001-2009 | ||
-- Copyright : (c) The University of Glasgow 2001-2016 | ||
-- License : BSD-style (see the file LICENSE) | ||
-- | ||
-- Maintainer : [email protected] | ||
|
@@ -57,7 +65,7 @@ | |
-- @since 1.1.0.0 | ||
module Control.DeepSeq ( | ||
deepseq, ($!!), force, | ||
NFData(..), | ||
NFData(..), rnfFoldableLTR, rnfFoldableRTL | ||
) where | ||
|
||
import Control.Applicative | ||
|
@@ -72,6 +80,7 @@ import Data.Array | |
import Data.Fixed | ||
import Data.Version | ||
import Data.Monoid as Mon | ||
import Data.Foldable (Foldable (foldMap)) | ||
import Data.Unique ( Unique ) | ||
import Foreign.Ptr | ||
import Foreign.C.Types | ||
|
@@ -105,6 +114,10 @@ import GHC.Stack ( CallStack(..) ) | |
import GHC.SrcLoc ( SrcLoc(..) ) | ||
#endif | ||
|
||
#if __GLASGOW_HASKELL__ >= 708 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I disagree. The whole There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, it's not something that personally bothers me that much, but I know @hvr has been wanting to be able to decouple There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, in general I dislike In this case, however, it's not so clear cut IMHO, as PS: Also, |
||
import Data.Coerce | ||
#endif | ||
|
||
#if __GLASGOW_HASKELL__ >= 702 | ||
import GHC.Fingerprint.Type ( Fingerprint(..) ) | ||
import GHC.Generics | ||
|
@@ -202,6 +215,87 @@ f $!! x = x `deepseq` f x | |
force :: (NFData a) => a -> a | ||
force x = x `deepseq` x | ||
|
||
newtype UnitLTR = UnitLTR {getUnitLTR :: ()} | ||
|
||
#if MIN_VERSION_base(4,9,0) | ||
instance Semi.Semigroup UnitLTR where | ||
UnitLTR () <> y = y | ||
#endif | ||
|
||
instance Monoid UnitLTR where | ||
mempty = UnitLTR () | ||
UnitLTR () `mappend` y = y | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To avoid invoking the wrath of instance Monoid UnitLTR where
mempty = UnitLTR ()
#if MIN_VERSION_base(4,9,0)
mappend = (<>)
#else
UnitLTR () `mappend` y = y
#endif And similarly for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. |
||
|
||
-- It would be nice to use Data.Monoid.Dual instead of | ||
-- another newtype, but that doesn't seem to inline | ||
-- very well if it doesn't specialize. | ||
newtype UnitRTL = UnitRTL {getUnitRTL :: ()} | ||
|
||
#if MIN_VERSION_base(4,9,0) | ||
instance Semi.Semigroup UnitRTL where | ||
x <> UnitRTL () = x | ||
#endif | ||
|
||
instance Monoid UnitRTL where | ||
mempty = UnitRTL () | ||
x `mappend` UnitRTL () = x | ||
|
||
-- | A definition of `rnf` for `Foldable` types that evaluates them | ||
-- from left to right. | ||
-- | ||
-- @ | ||
-- data ConsList a = Cons a (ConsList a) | Nil deriving (Foldable) | ||
-- instance NFData a => NFData (ConsList a) where | ||
-- rnf = rnfFoldableLTR | ||
-- @ | ||
-- | ||
-- Caution: this only works properly if the `Foldable` instance | ||
-- folds over all relevant structure. | ||
-- | ||
-- @ | ||
-- rnfFoldableLTR (Left undefined) = () | ||
-- rnfFoldableLTR (undefined, ()) = () | ||
-- @ | ||
#if __GLASGOW_HASKELL__ >= 708 | ||
rnfFoldableLTR :: forall f a . (Foldable f, NFData a) => f a -> () | ||
rnfFoldableLTR = getUnitLTR . foldMap (coerce (rnf :: a -> ())) | ||
#else | ||
rnfFoldableLTR :: (Foldable f, NFData a) => f a -> () | ||
rnfFoldableLTR = getUnitLTR . foldMap (UnitLTR . rnf) | ||
#endif | ||
|
||
-- | A definition of `rnf` for `Foldable` types that evaluates them | ||
-- from right to left. | ||
-- | ||
-- @ | ||
-- data SnocList a = Snoc (SnocList a) a | SNil deriving (Foldable) | ||
-- instance NFData a => NFData (SnocList a) where | ||
-- rnf = rnfFoldableRTL | ||
-- @ | ||
-- | ||
-- Caution: this only works properly if the `Foldable` instance | ||
-- folds over all relevant structure. | ||
-- | ||
-- @ | ||
-- rnfFoldableRTL (Left undefined) = () | ||
-- rnfFoldableRTL (undefined, ()) = () | ||
-- @ | ||
#if __GLASGOW_HASKELL__ >= 708 | ||
rnfFoldableRTL :: forall f a . (Foldable f, NFData a) => f a -> () | ||
rnfFoldableRTL = getUnitRTL . foldMap (coerce (rnf :: a -> ())) | ||
#else | ||
rnfFoldableRTL :: (Foldable f, NFData a) => f a -> () | ||
rnfFoldableRTL = getUnitRTL . foldMap (UnitRTL . rnf) | ||
#endif | ||
|
||
#ifdef __GLASGOW_HASKELL__ | ||
{-# INLINABLE rnfFoldableLTR #-} | ||
{-# INLINABLE rnfFoldableRTL #-} | ||
#else | ||
{-# INLINE rnfFoldableLTR #-} | ||
{-# INLINE rnfFoldableRTL #-} | ||
#endif | ||
|
||
-- | A class of types that can be fully evaluated. | ||
-- | ||
-- @since 1.1.0.0 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,6 +53,11 @@ library | |
if impl(ghc < 7.6) | ||
build-depends: ghc-prim == 0.2.* | ||
|
||
if impl(ghc >= 7.8) | ||
other-extensions: | ||
ScopedTypeVariables | ||
Trustworthy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are these here if you enable them in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not really important. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, I misread the phrase Hm, the current full list of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ack, I misread again. I was looking at the So it's really only the placement of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @RyanGlScott actually, |
||
|
||
if impl(ghc < 7.4) | ||
build-depends: array < 0.4 | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to enable
ScopedTypeVariables
unconditionally (without an#ifdef
), since all versions of GHC that we test against supportScopedTypeVariables
anyway.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine.