[commit: packages/containers] develop-0.6, develop-0.6-questionable, master: Remove unsafeCoerce, use only coerce on GHC 7.8 and later. (b38f240)
git at git.haskell.org
git at git.haskell.org
Fri Dec 18 22:10:14 UTC 2015
Repository : ssh://git@git.haskell.org/containers
On branches: develop-0.6,develop-0.6-questionable,master
Link : http://git.haskell.org/packages/containers.git/commitdiff/b38f240ab4bec53c5f5800cc1b621a00b4604b2d
>---------------------------------------------------------------
commit b38f240ab4bec53c5f5800cc1b621a00b4604b2d
Author: Milan Straka <fox at ucw.cz>
Date: Mon Dec 15 09:02:37 2014 +0100
Remove unsafeCoerce, use only coerce on GHC 7.8 and later.
Also, move the conditional compilation to a local where definition.
On my GHC 7.6.3, there is no heap allocation in the cmm in fromFunction
for the (Elem . f) closure, so there is no penalty of not using `coerce`.
Nevertheless, GHC 7.8.3 and GHC-head (15 Dec 2014) do heap-allocate
trivial closure for (Elem . f), so `coerce` helps.
Back to GHC 7.6.3, I found that the following does not allocate in
GHC 7.6.3:
newtype Elem a = Elem a
elemMap :: Int -> (Int -> b) -> [Elem b]
elemMap s f = go (Elem . f) 0
where go :: (Int -> b) -> Int -> [b]
go f i | i >= s = []
| otherwise = f i : go f (i+1)
Nevertheless, the following does heap-allocate trivial closure for f:
newtype Elem a = Elem a
elemMap :: [Int] -> (Int -> b) -> [Elem b]
elemMap xs f = go (Elem . f) xs
where go :: (Int -> b) -> [Int] -> [b]
go f [] = []
go f (x:xs) = f x : go f xs
I am not sure what the difference is, but the current fromFunction
does not allocate too (on 7.6.3).
>---------------------------------------------------------------
b38f240ab4bec53c5f5800cc1b621a00b4604b2d
Data/Sequence.hs | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/Data/Sequence.hs b/Data/Sequence.hs
index fa80b3f..4c281fc 100644
--- a/Data/Sequence.hs
+++ b/Data/Sequence.hs
@@ -181,14 +181,7 @@ import Data.Data
#if __GLASGOW_HASKELL__ >= 708
import Data.Coerce
import qualified GHC.Exts
-#define COERCE coerce
#else
-#ifdef __GLASGOW_HASKELL__
-import qualified Unsafe.Coerce
--- Note that by compiling this file with GHC 7.8 or later, we prove that
--- it is safe to use COERCE with earlier GHC versions.
-#define COERCE Unsafe.Coerce.unsafeCoerce
-#endif
#endif
#if MIN_VERSION_base(4,8,0)
import Data.Functor.Identity (Identity(..))
@@ -1365,11 +1358,7 @@ mapWithIndex f' (Seq xs') = Seq $ mapWithIndexTree (\s (Elem a) -> Elem (f' s a)
fromFunction :: Int -> (Int -> a) -> Seq a
fromFunction len f | len < 0 = error "Data.Sequence.fromFunction called with negative len"
| len == 0 = empty
-#ifdef __GLASGOW_HASKELL__
- | otherwise = Seq $ create (COERCE f) 1 0 len
-#else
- | otherwise = Seq $ create (Elem . f) 1 0 len
-#endif
+ | otherwise = Seq $ create (lift_elem f) 1 0 len
where
create :: (Int -> a) -> Int -> Int -> Int -> FingerTree a
create b{-tree_builder-} s{-tree_size-} i{-start_index-} trees = i `seq` s `seq` case trees of
@@ -1397,6 +1386,14 @@ fromFunction len f | len < 0 = error "Data.Sequence.fromFunction called with neg
mb j = Node3 (3*s) (b j) (b (j + s)) (b (j + 2*s))
{-# INLINE mb #-}
+ lift_elem :: (Int -> a) -> (Int -> Elem a)
+#if __GLASGOW_HASKELL__ >= 708
+ lift_elem g = coerce g
+#else
+ lift_elem g = Elem . g
+#endif
+ {-# INLINE lift_elem #-}
+
-- Splitting
-- | /O(log(min(i,n-i)))/. The first @i@ elements of a sequence.
More information about the ghc-commits
mailing list