Skip to content

Commit b38f240

Browse files
committed
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).
1 parent 97599c0 commit b38f240

File tree

1 file changed

+9
-12
lines changed

1 file changed

+9
-12
lines changed

Data/Sequence.hs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,7 @@ import Data.Data
181181
#if __GLASGOW_HASKELL__ >= 708
182182
import Data.Coerce
183183
import qualified GHC.Exts
184-
#define COERCE coerce
185184
#else
186-
#ifdef __GLASGOW_HASKELL__
187-
import qualified Unsafe.Coerce
188-
-- Note that by compiling this file with GHC 7.8 or later, we prove that
189-
-- it is safe to use COERCE with earlier GHC versions.
190-
#define COERCE Unsafe.Coerce.unsafeCoerce
191-
#endif
192185
#endif
193186
#if MIN_VERSION_base(4,8,0)
194187
import Data.Functor.Identity (Identity(..))
@@ -1365,11 +1358,7 @@ mapWithIndex f' (Seq xs') = Seq $ mapWithIndexTree (\s (Elem a) -> Elem (f' s a)
13651358
fromFunction :: Int -> (Int -> a) -> Seq a
13661359
fromFunction len f | len < 0 = error "Data.Sequence.fromFunction called with negative len"
13671360
| len == 0 = empty
1368-
#ifdef __GLASGOW_HASKELL__
1369-
| otherwise = Seq $ create (COERCE f) 1 0 len
1370-
#else
1371-
| otherwise = Seq $ create (Elem . f) 1 0 len
1372-
#endif
1361+
| otherwise = Seq $ create (lift_elem f) 1 0 len
13731362
where
13741363
create :: (Int -> a) -> Int -> Int -> Int -> FingerTree a
13751364
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
13971386
mb j = Node3 (3*s) (b j) (b (j + s)) (b (j + 2*s))
13981387
{-# INLINE mb #-}
13991388

1389+
lift_elem :: (Int -> a) -> (Int -> Elem a)
1390+
#if __GLASGOW_HASKELL__ >= 708
1391+
lift_elem g = coerce g
1392+
#else
1393+
lift_elem g = Elem . g
1394+
#endif
1395+
{-# INLINE lift_elem #-}
1396+
14001397
-- Splitting
14011398

14021399
-- | /O(log(min(i,n-i)))/. The first @i@ elements of a sequence.

0 commit comments

Comments
 (0)