Reexport scanl' (#74)

This is useful for the same reasons that foldl' is useful
This commit is contained in:
Moritz Kiefer
2017-12-18 19:03:45 +00:00
committed by Stephen Diehl
parent d462550f07
commit 2d8d1f3357
2 changed files with 41 additions and 0 deletions
+1
View File
@@ -781,6 +781,7 @@
* runStateT
* scaleFloat
* scanl
* scanl'
* scanr
* second
* selName
+40
View File
@@ -1,3 +1,4 @@
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE FlexibleContexts #-}
@@ -27,6 +28,7 @@ module Protolude (
liftIO2,
#if !MIN_VERSION_base(4,8,0)
(&),
scanl',
#endif
die,
) where
@@ -177,6 +179,9 @@ import Data.List as X (
, subsequences
, permutations
, scanl
#if MIN_VERSION_base(4,8,0)
, scanl'
#endif
, scanr
, iterate
, repeat
@@ -197,6 +202,12 @@ import Data.List as X (
, genericReplicate
)
#if !MIN_VERSION_base(4,8,0)
-- These imports are required for the scanl' rewrite rules
import GHC.Exts (build)
import Data.List (tail)
#endif
-- Hashing
import Data.Hashable as X (
Hashable
@@ -619,3 +630,32 @@ die err = System.Exit.die (toS err)
die :: Text -> IO a
die err = hPutStrLn stderr err >> exitFailure
#endif
#if !MIN_VERSION_base(4,8,0)
-- This is a literal copy of the implementation in GHC.List in base-4.10.1.0.
-- | A strictly accumulating version of 'scanl'
{-# NOINLINE [1] scanl' #-}
scanl' :: (b -> a -> b) -> b -> [a] -> [b]
scanl' = scanlGo'
where
scanlGo' :: (b -> a -> b) -> b -> [a] -> [b]
scanlGo' f !q ls = q : (case ls of
[] -> []
x:xs -> scanlGo' f (f q x) xs)
{-# RULES
"scanl'" [~1] forall f a bs . scanl' f a bs =
build (\c n -> a `c` foldr (scanlFB' f c) (flipSeqScanl' n) bs a)
"scanlList'" [1] forall f a bs .
foldr (scanlFB' f (:)) (flipSeqScanl' []) bs a = tail (scanl' f a bs)
#-}
{-# INLINE [0] scanlFB' #-}
scanlFB' :: (b -> a -> b) -> (b -> c -> c) -> a -> (b -> c) -> b -> c
scanlFB' f c = \b g -> \x -> let !b' = f x b in b' `c` g b'
{-# INLINE [0] flipSeqScanl' #-}
flipSeqScanl' :: a -> b -> a
flipSeqScanl' a !_b = a
#endif