diff --git a/vector/src/Data/Vector/Fusion/Bundle/Monadic.hs b/vector/src/Data/Vector/Fusion/Bundle/Monadic.hs index 6e51532f..ef70add4 100644 --- a/vector/src/Data/Vector/Fusion/Bundle/Monadic.hs +++ b/vector/src/Data/Vector/Fusion/Bundle/Monadic.hs @@ -7,6 +7,7 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} -- | -- Module : Data.Vector.Fusion.Bundle.Monadic -- Copyright : (c) Roman Leshchinskiy 2008-2010 @@ -750,7 +751,7 @@ scanl' f = scanlM' (\a b -> return (f a b)) -- | Haskell-style scan with strict accumulator and a monadic operator scanlM' :: Monad m => (a -> b -> m a) -> a -> Bundle m v b -> Bundle m v a {-# INLINE scanlM' #-} -scanlM' f z s = z `seq` (z `cons` postscanlM f z s) +scanlM' f !z s = z `cons` postscanlM f z s -- | Initial-value free scan over a 'Bundle' scanl1 :: Monad m => (a -> a -> a) -> Bundle m v a -> Bundle m v a @@ -800,7 +801,7 @@ enumFromTo x y = fromList [x .. y] -- FIXME: add "too large" test for Int enumFromTo_small :: (Integral a, Monad m) => a -> a -> Bundle m v a {-# INLINE_FUSED enumFromTo_small #-} -enumFromTo_small x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exact n) +enumFromTo_small !x !y = fromStream (Stream step (Just x)) (Exact n) where n = delay_inline max (fromIntegral y - fromIntegral x + 1) 0 @@ -810,33 +811,6 @@ enumFromTo_small x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exact | z < y = return $ Yield z (Just (z+1)) | otherwise = return $ Done -{-# RULES - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_small :: Monad m => Int8 -> Int8 -> Bundle m v Int8 - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_small :: Monad m => Int16 -> Int16 -> Bundle m v Int16 - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_small :: Monad m => Word8 -> Word8 -> Bundle m v Word8 - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_small :: Monad m => Word16 -> Word16 -> Bundle m v Word16 #-} - - - -#if WORD_SIZE_IN_BITS > 32 - -{-# RULES - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_small :: Monad m => Int32 -> Int32 -> Bundle m v Int32 - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_small :: Monad m => Word32 -> Word32 -> Bundle m v Word32 #-} - -#endif -- NOTE: We could implement a generic "too large" test: -- @@ -852,7 +826,7 @@ enumFromTo_small x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exact enumFromTo_int :: forall m v. (HasCallStack, Monad m) => Int -> Int -> Bundle m v Int {-# INLINE_FUSED enumFromTo_int #-} -enumFromTo_int x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exact (len x y)) +enumFromTo_int !x !y = fromStream (Stream step (Just x)) (Exact (len x y)) where {-# INLINE [0] len #-} len :: HasCallStack => Int -> Int -> Int @@ -869,7 +843,7 @@ enumFromTo_int x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exact (l enumFromTo_intlike :: forall m v a. (HasCallStack, Integral a, Monad m) => a -> a -> Bundle m v a {-# INLINE_FUSED enumFromTo_intlike #-} -enumFromTo_intlike x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exact (len x y)) +enumFromTo_intlike !x !y = fromStream (Stream step (Just x)) (Exact (len x y)) where {-# INLINE [0] len #-} len :: HasCallStack => a -> a -> Int @@ -886,28 +860,12 @@ enumFromTo_intlike x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exac | z < y = return $ Yield z (Just (z+1)) | otherwise = return $ Done -{-# RULES - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_int :: Monad m => Int -> Int -> Bundle m v Int - -#if WORD_SIZE_IN_BITS > 32 - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_intlike :: Monad m => Int64 -> Int64 -> Bundle m v Int64 #-} - -#else - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_intlike :: Monad m => Int32 -> Int32 -> Bundle m v Int32 #-} - -#endif enumFromTo_big_word :: forall m v a. (HasCallStack, Integral a, Monad m) => a -> a -> Bundle m v a {-# INLINE_FUSED enumFromTo_big_word #-} -enumFromTo_big_word x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exact (len x y)) +enumFromTo_big_word !x !y = fromStream (Stream step (Just x)) (Exact (len x y)) where {-# INLINE [0] len #-} len :: HasCallStack => a -> a -> Int @@ -924,34 +882,13 @@ enumFromTo_big_word x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exa | z < y = return $ Yield z (Just (z+1)) | otherwise = return $ Done -{-# RULES -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_big_word :: Monad m => Word -> Word -> Bundle m v Word - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_big_word - :: Monad m => Word64 -> Word64 -> Bundle m v Word64 #if WORD_SIZE_IN_BITS == 32 - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_big_word - :: Monad m => Word32 -> Word32 -> Bundle m v Word32 - -#endif - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_big_word - :: Monad m => Integer -> Integer -> Bundle m v Integer #-} - - -#if WORD_SIZE_IN_BITS > 32 - -- FIXME: the "too large" test is totally wrong enumFromTo_big_int :: forall m v a. (HasCallStack, Integral a, Monad m) => a -> a -> Bundle m v a {-# INLINE_FUSED enumFromTo_big_int #-} -enumFromTo_big_int x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exact (len x y)) +enumFromTo_big_int !x !y = fromStream (Stream step (Just x)) (Exact (len x y)) where {-# INLINE [0] len #-} len :: HasCallStack => a -> a -> Int @@ -967,20 +904,11 @@ enumFromTo_big_int x y = x `seq` y `seq` fromStream (Stream step (Just x)) (Exac step (Just z) | z == y = return $ Yield z Nothing | z < y = return $ Yield z (Just (z+1)) | otherwise = return $ Done - - -{-# RULES - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_big_int :: Monad m => Int64 -> Int64 -> Bundle m v Int64 #-} - - - #endif enumFromTo_char :: Monad m => Char -> Char -> Bundle m v Char {-# INLINE_FUSED enumFromTo_char #-} -enumFromTo_char x y = x `seq` y `seq` fromStream (Stream step xn) (Exact n) +enumFromTo_char !x !y = fromStream (Stream step xn) (Exact n) where xn = ord x yn = ord y @@ -991,11 +919,6 @@ enumFromTo_char x y = x `seq` y `seq` fromStream (Stream step xn) (Exact n) step zn | zn <= yn = return $ Yield (unsafeChr zn) (zn+1) | otherwise = return $ Done -{-# RULES - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_char #-} - ------------------------------------------------------------------------ @@ -1005,7 +928,7 @@ enumFromTo_char x y = x `seq` y `seq` fromStream (Stream step xn) (Exact n) enumFromTo_double :: forall m v a. (HasCallStack, Monad m, Ord a, RealFrac a) => a -> a -> Bundle m v a {-# INLINE_FUSED enumFromTo_double #-} -enumFromTo_double n m = n `seq` m `seq` fromStream (Stream step ini) (Max (len n lim)) +enumFromTo_double !n !m = fromStream (Stream step ini) (Max (len n lim)) where lim = m + 1/2 -- important to float out @@ -1025,14 +948,36 @@ enumFromTo_double n m = n `seq` m `seq` fromStream (Stream step ini) (Max (len n x' = x + n {-# RULES +"enumFromTo [Bundle]" enumFromTo @Int8 = enumFromTo_small +"enumFromTo [Bundle]" enumFromTo @Int16 = enumFromTo_small +"enumFromTo [Bundle]" enumFromTo @Word8 = enumFromTo_small +"enumFromTo [Bundle]" enumFromTo @Word16 = enumFromTo_small -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_double :: Monad m => Double -> Double -> Bundle m v Double - -"enumFromTo [Bundle]" - enumFromTo = enumFromTo_double :: Monad m => Float -> Float -> Bundle m v Float #-} +"enumFromTo [Bundle]" enumFromTo @Int = enumFromTo_int +"enumFromTo [Bundle]" enumFromTo @Word = enumFromTo_big_word +"enumFromTo [Bundle]" enumFromTo @Word64 = enumFromTo_big_word +"enumFromTo [Bundle]" enumFromTo @Integer = enumFromTo_big_word +"enumFromTo [Bundle]" enumFromTo @Char = enumFromTo_char +"enumFromTo [Bundle]" enumFromTo @Double = enumFromTo_double +"enumFromTo [Bundle]" enumFromTo @Float = enumFromTo_double + #-} +#if WORD_SIZE_IN_BITS > 32 +-- 64bit systems +{-# RULES +"enumFromTo [Bundle]" enumFromTo @Int32 = enumFromTo_small +"enumFromTo [Bundle]" enumFromTo @Int64 = enumFromTo_intlike +"enumFromTo [Bundle]" enumFromTo @Word32 = enumFromTo_small + #-} +#else +-- 32bit systems +{-# RULES +"enumFromTo [Bundle]" enumFromTo @Int32 = enumFromTo_intlike +"enumFromTo [Bundle]" enumFromTo @Word32 = enumFromTo_big_word +"enumFromTo [Bundle]" enumFromTo @Int64 = enumFromTo_big_int + #-} +#endif ------------------------------------------------------------------------ @@ -1071,7 +1016,7 @@ unsafeFromList sz xs = fromStream (S.fromList xs) sz fromVector :: (Monad m, Vector v a) => v a -> Bundle m v a {-# INLINE_FUSED fromVector #-} -fromVector v = v `seq` n `seq` Bundle (Stream step 0) +fromVector !v = n `seq` Bundle (Stream step 0) (Stream vstep True) (Just v) (Exact n)