Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions Data/Primitive/Array.hs
Original file line number Diff line number Diff line change
Expand Up @@ -586,18 +586,28 @@ 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.

-- Note [fromListN]
-- ~~~~~~~~~~~~~~~~
-- We want arrayFromListN to be a "good consumer" in list fusion, so we define
-- the function using foldr and inline it to help fire fusion rules.
-- If fusion occurs with a "good producer", it may reduce to a fold on some
-- structure. In certain cases (such as for Data.Set) GHC is not be able to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is best to move this sentence ("In certain cases (such as for Data.Set) GHC is not be able to ...") to a comment into the body of the function, since that is not relevant information for the user.

Suggested change
-- structure. In certain cases (such as for Data.Set) GHC is not be able to
-- structure. In certain cases (such as for Data.Set) GHC is not able to

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which "user" do you mean? This comment block is not part of the Haddocks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, you are right. I did not notice an empty new line on line number 589 between the haddock and the comment.

-- optimize the index to an unboxed Int# (see GHC #24628), so we explicitly use
-- an Int# here.
arrayFromListN :: Int -> [a] -> Array a
{-# INLINE arrayFromListN #-}
arrayFromListN n l =
createArray n (die "fromListN" "uninitialized element") $ \sma ->
let go !ix [] = if ix == n
let z ix# = if I# 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 I# ix# < n
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewthad You didn't need to drop support for ghc-8.0 in #426, since oneShot is available form ghc-prim for a very long time, so it could have been imported from GHC.Magic for all GHC versions, instead of relying on CPP. Especially since the test suite already depends on ghc-prim. Seems like a very minor thing to drop support for a whole ghc version, but I personally not gonna cry over it 🥲

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I would've needed to add the dependency on ghc-prim back to primitive, and it was so nice to finally have it gone. Dropping GHC 8.0 has the additional advantage of letting me delete several shims in #427. I'll probably end up dropping support for all GHCs earlier than 8.6 soon.

then do
writeArray sma ix x
go (ix+1) xs
writeArray sma (I# ix#) x
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
Expand Down
13 changes: 8 additions & 5 deletions Data/Primitive/ByteArray.hs
Original file line number Diff line number Diff line change
Expand Up @@ -378,17 +378,20 @@ 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.

-- See Note [fromListN] in Data.Primitive.Array
byteArrayFromListN :: forall a. Prim a => Int -> [a] -> ByteArray
{-# INLINE byteArrayFromListN #-}
byteArrayFromListN n ys = createByteArray (n * sizeOfType @a) $ \marr ->
let go !ix [] = if ix == n
let z ix# = if I# 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 I# ix# < n
then do
writeByteArray marr ix x
go (ix + 1) xs
writeByteArray marr (I# ix#) x
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#
Expand Down
13 changes: 8 additions & 5 deletions Data/Primitive/PrimArray.hs
Original file line number Diff line number Diff line change
Expand Up @@ -234,17 +234,20 @@ 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.

-- See Note [fromListN] in Data.Primitive.Array
primArrayFromListN :: forall a. Prim a => Int -> [a] -> PrimArray a
{-# INLINE primArrayFromListN #-}
primArrayFromListN len vs = createPrimArray len $ \arr ->
let go [] !ix = if ix == len
let z ix# = if I# 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 I# ix# < len
then do
writePrimArray arr ix a
go as (ix + 1)
writePrimArray arr (I# ix#) a
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 #-}
Expand Down
11 changes: 6 additions & 5 deletions Data/Primitive/SmallArray.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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 #-}
smallArrayFromListN n l =
createSmallArray n
(die "smallArrayFromListN" "uninitialized element") $ \sma ->
let go !ix [] = if ix == n
let z ix# = if I# 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 I# ix# < n
then do
writeSmallArray sma ix x
go (ix + 1) xs
writeSmallArray sma (I# ix#) x
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
Expand Down
Loading