Commit b6533af4 authored by Simon Marlow's avatar Simon Marlow
Browse files

fix strictness of foldr/build rule for take, see #1219

parent 6760c51d
......@@ -350,10 +350,16 @@ splitAt n xs = (take n xs, drop n xs)
#else /* hack away */
{-# RULES
"take" [~1] forall n xs . take n xs = case n of I# n# -> build (\c nil -> foldr (takeFB c nil) (takeConst nil) xs n#)
"take" [~1] forall n xs . take n xs = takeFoldr n xs
"takeList" [1] forall n xs . foldr (takeFB (:) []) (takeConst []) xs n = takeUInt n xs
#-}
{-# INLINE takeFoldr #-}
takeFoldr :: Int -> [a] -> [a]
takeFoldr (I# n#) xs
= build (\c nil -> if n# <=# 0# then nil else
foldr (takeFB c nil) (takeConst nil) xs n#)
{-# NOINLINE [0] takeConst #-}
-- just a version of const that doesn't get inlined too early, so we
-- can spot it in rules. Also we need a type sig due to the unboxed Int#.
......@@ -361,8 +367,8 @@ takeConst :: a -> Int# -> a
takeConst x _ = x
{-# NOINLINE [0] takeFB #-}
takeFB :: (a -> b -> c) -> c -> a -> (Int# -> b) -> Int# -> c
takeFB c n x xs m | m <=# 0# = n
takeFB :: (a -> b -> b) -> b -> a -> (Int# -> b) -> Int# -> b
takeFB c n x xs m | m <=# 1# = x `c` n
| otherwise = x `c` xs (m -# 1#)
{-# INLINE [0] take #-}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment