diff --git a/Data/Primitive/Array.hs b/Data/Primitive/Array.hs index c527c60..d1e851c 100644 --- a/Data/Primitive/Array.hs +++ b/Data/Primitive/Array.hs @@ -587,17 +587,18 @@ mapArray' f a = -- | Create an array from a list of a known length. If the length -- of the list does not match the given length, this throws an exception. arrayFromListN :: Int -> [a] -> Array a +{-# INLINE arrayFromListN #-} -- Inline for list fusion arrayFromListN n l = createArray n (die "fromListN" "uninitialized element") $ \sma -> - let go !ix [] = if ix == n + let z !ix = if ix == n then return () else die "fromListN" "list length less than specified size" - go !ix (x : xs) = if ix < n + f x k = GHC.Exts.oneShot $ \ !ix -> if ix < n then do writeArray sma ix x - go (ix+1) xs + k (ix+1) else die "fromListN" "list length greater than specified size" - in go 0 l + in foldr f z l 0 -- | Create an array from a list. arrayFromList :: [a] -> Array a diff --git a/Data/Primitive/ByteArray.hs b/Data/Primitive/ByteArray.hs index 4cd935b..ea50bf1 100644 --- a/Data/Primitive/ByteArray.hs +++ b/Data/Primitive/ByteArray.hs @@ -379,16 +379,17 @@ byteArrayFromList xs = byteArrayFromListN (length xs) xs -- | Create a 'ByteArray' from a list of a known length. If the length -- of the list does not match the given length, this throws an exception. byteArrayFromListN :: forall a. Prim a => Int -> [a] -> ByteArray +{-# INLINE byteArrayFromListN #-} -- Inline for list fusion byteArrayFromListN n ys = createByteArray (n * sizeOfType @a) $ \marr -> - let go !ix [] = if ix == n + let z !ix = if ix == n then return () else die "byteArrayFromListN" "list length less than specified size" - go !ix (x : xs) = if ix < n + f x k = GHC.Exts.oneShot $ \ !ix -> if ix < n then do writeByteArray marr ix x - go (ix + 1) xs + k (ix + 1) else die "byteArrayFromListN" "list length greater than specified size" - in go 0 ys + in foldr f z ys 0 unI# :: Int -> Int# unI# (I# n#) = n# diff --git a/Data/Primitive/PrimArray.hs b/Data/Primitive/PrimArray.hs index 5c2b9e0..1d20dbf 100644 --- a/Data/Primitive/PrimArray.hs +++ b/Data/Primitive/PrimArray.hs @@ -235,16 +235,17 @@ primArrayFromList vs = primArrayFromListN (L.length vs) vs -- | Create a 'PrimArray' from a list of a known length. If the length -- of the list does not match the given length, this throws an exception. primArrayFromListN :: forall a. Prim a => Int -> [a] -> PrimArray a +{-# INLINE primArrayFromListN #-} -- Inline for list fusion primArrayFromListN len vs = createPrimArray len $ \arr -> - let go [] !ix = if ix == len + let z !ix = if ix == len then return () else die "fromListN" "list length less than specified size" - go (a : as) !ix = if ix < len + f a k = GHC.Exts.oneShot $ \ !ix -> if ix < len then do writePrimArray arr ix a - go as (ix + 1) + k (ix + 1) else die "fromListN" "list length greater than specified size" - in go vs 0 + in foldr f z vs 0 -- | Convert a 'PrimArray' to a list. {-# INLINE primArrayToList #-} diff --git a/Data/Primitive/SmallArray.hs b/Data/Primitive/SmallArray.hs index 74c8fbf..8794669 100644 --- a/Data/Primitive/SmallArray.hs +++ b/Data/Primitive/SmallArray.hs @@ -924,18 +924,19 @@ instance (Typeable s, Typeable a) => Data (SmallMutableArray s a) where -- | Create a 'SmallArray' from a list of a known length. If the length -- of the list does not match the given length, this throws an exception. smallArrayFromListN :: Int -> [a] -> SmallArray a +{-# INLINE smallArrayFromListN #-} -- Inline for list fusion smallArrayFromListN n l = createSmallArray n (die "smallArrayFromListN" "uninitialized element") $ \sma -> - let go !ix [] = if ix == n + let z !ix = if ix == n then return () else die "smallArrayFromListN" "list length less than specified size" - go !ix (x : xs) = if ix < n + f x k = GHC.Exts.oneShot $ \ !ix -> if ix < n then do writeSmallArray sma ix x - go (ix + 1) xs + k (ix + 1) else die "smallArrayFromListN" "list length greater than specified size" - in go 0 l + in foldr f z l 0 -- | Create a 'SmallArray' from a list. smallArrayFromList :: [a] -> SmallArray a