Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

foldMap, foldMap' for PrimArray #186

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

chessai
Copy link
Member

@chessai chessai commented Jul 15, 2018

No description provided.

@andrewthad
Copy link
Collaborator

I'm good with this. If there aren't any objection in the next few days, I'll merge this.

@RyanGlScott
Copy link
Member

No objections here, although these deserve to be mentioned in the changelog.

@chessai
Copy link
Member Author

chessai commented Jul 16, 2018

Sorry I keep forgetting that. I'll add it in.

@chessai
Copy link
Member Author

chessai commented Sep 17, 2018

Is this good to be merged? The travis failure is unrelated.

foldMapPrimArray f = foldrPrimArray (\a acc -> acc `mappend` f a) mempty

-- | Strictly map each element of the primitive array to a monoid, and combine the results.
foldMapPrimArray' :: forall a m. (Prim a, Monoid m) => (a -> m) -> PrimArray a -> m
Copy link
Collaborator

Choose a reason for hiding this comment

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

The documentation is insufficient. It should explain which way the combination associates. Also, it's notably not (necessarily) strict in the function results. The documentation should reflect this and there should be a comment explaining that decision.

@@ -467,6 +469,16 @@ sizeofPrimArray :: forall a. Prim a => PrimArray a -> Int
{-# INLINE sizeofPrimArray #-}
sizeofPrimArray (PrimArray arr#) = I# (quotInt# (sizeofByteArray# arr#) (sizeOf# (undefined :: a)))

-- | Lazily map each element of the primitive array to a monoid, and combine the results.
foldMapPrimArray :: forall a m. (Prim a, Monoid m) => (a -> m) -> PrimArray a -> m
Copy link
Collaborator

Choose a reason for hiding this comment

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

The documentation is insufficient. It should explain how the combination associates. In fact, I think we should almost surely offer more than one version: associating to the left, associating to the right, and (for certain tree-like monoids) associating in a balanced fashion are all potentially useful.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Tree-like or in some cases numerical. Balanced association can reduce floating point errors somewhat, for example.

@treeowl
Copy link
Collaborator

treeowl commented Sep 17, 2018

Sorry for the delayed review

@chessai
Copy link
Member Author

chessai commented Sep 17, 2018

That is okay, this is valuable feedback. I will make these changes shortly.

Data/Primitive/PrimArray.hs Outdated Show resolved Hide resolved
@chessai
Copy link
Member Author

chessai commented Sep 17, 2018

most recent commit does not add balanced foldMap. I think I'd prefer for that to be in a separate PR, as it's a little more complicated.

@@ -467,6 +471,32 @@ sizeofPrimArray :: forall a. Prim a => PrimArray a -> Int
{-# INLINE sizeofPrimArray #-}
sizeofPrimArray (PrimArray arr#) = I# (quotInt# (sizeofByteArray# arr#) (sizeOf# (undefined :: a)))

-- | Map each element of the primitive array to a monoid, and combine the results.
-- The combination is right-associated, and the accumulation is lazy.
foldrMapPrimArray :: forall a m. (Prim a, Monoid m) => (a -> m) -> PrimArray a -> m
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd rather see the Map before the r.

Data/Primitive/PrimArray.hs Show resolved Hide resolved

-- | Map each element of the primitive array to a monoid, and combine the results.
-- The combination is right-associated, and the accumulation is strict, though
-- this function is not necessarily strict in its result.
Copy link
Collaborator

Choose a reason for hiding this comment

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

"This function is not necessarily strict in its result" doesn't mean anything whatsoever to me. What I meant needed explanation is that at each step, we force the accumulator value, but we don't force the value of f a. So if mappend is lazy in its first argument, f a will not be evaluated. This is probably the correct behavior, but needs better explanation.

changelog.md Outdated
@@ -29,7 +29,9 @@

## Changes in version 0.6.4.1

* Add instances for the following newtypes from `base`:
* Add `foldMapPrimArray` and `foldMapPrimArray'`
Copy link
Collaborator

Choose a reason for hiding this comment

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

This needs to be updated now that you've added more functions.

@chessai
Copy link
Member Author

chessai commented Sep 18, 2018

requested changes attempted, @treeowl

Copy link
Collaborator

@treeowl treeowl left a comment

Choose a reason for hiding this comment

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

Much better. Just a couple more little changes.

Data/Primitive/PrimArray.hs Show resolved Hide resolved
Data/Primitive/PrimArray.hs Outdated Show resolved Hide resolved
@treeowl
Copy link
Collaborator

treeowl commented Sep 18, 2018 via email

@chessai
Copy link
Member Author

chessai commented Sep 18, 2018

Both examples are supposed to show associativity. I think they can be much
briefer, TBH. Just give a three-element example application and show how it
unfolds as a single expression.

By 'briefer', do you mean less 'tutorial-like', to assume that the example is illustrative enough sans written explanation?

@treeowl
Copy link
Collaborator

treeowl commented Sep 18, 2018

By 'briefer', do you mean less 'tutorial-like', to assume that the example is illustrative enough sans written explanation?

Right. This is primitive, not base or containers. Users are expected to know what they're doing. But language is slippery, so "associates to the left" might well evoke opposite meanings in the minds of two different people.

@chessai
Copy link
Member Author

chessai commented Sep 18, 2018

Right. This is primitive, not base or containers. Users are expected to know what they're doing. But language is slippery, so "associates to the left" might well evoke opposite meanings in the minds of two different people.

Makes sense - understood

@treeowl
Copy link
Collaborator

treeowl commented Sep 18, 2018 via email

@chessai
Copy link
Member Author

chessai commented Sep 18, 2018

@treeowl Examples are now simplified and function values are being forced

@treeowl
Copy link
Collaborator

treeowl commented Sep 18, 2018 via email

@chessai
Copy link
Member Author

chessai commented Sep 18, 2018

OK

@andrewthad
Copy link
Collaborator

I like the stuff in the PR, although I dislike the naming convention that @treeowl suggested. I actually prefer foldrMapPrimArray to foldMapRPrimArray. Anyone else got any thoughts on the color of the bikeshed?

@Boarders
Copy link
Contributor

I would still like this and also a foldl for ByteArray at some point. Happy to help to make that happen in whatever way I can.

@andrewthad
Copy link
Collaborator

I'll change the names and merge this. @Boarders Open a separate PR for a foldl on ByteArray. You should be able to nearly copy and paste the foldl on PrimArray.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants