Skip to content

Conversation

@matthewleon
Copy link
Contributor

Following discussion at purescript-deprecated/purescript-eff#22 (comment)

The purescript-unsafe-coerce dep can be removed if purescript-deprecated/purescript-eff#23 is accepted.

Would particularly like input on the documentation.

Also, I have not made Functor a superclass. I'm happy to change that, but so far I haven't seen anything that makes it a requirement, or beneficial.

@paf31
Copy link
Contributor

paf31 commented Jun 9, 2017

I was originally thinking this could go into eff actually, or even be its own library.

-- | be written for the Eff monad. For an example, see `iterableArray`,
-- | below.

class Iterable i where
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that I think about it more, this might not be the best name. Other languages use this name for something more like generators.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Foreachable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If this approach is still part of the discussion, then I'm thinking something like FoldableE and TraversableE, since really what is being proposed are just optimized versions for Eff of these two classes, and this follows the precedent of foreachE.

@matthewleon
Copy link
Contributor Author

I was originally thinking this could go into eff actually, or even be its own library.

Sure. I didn't think too much about where to put it... Was happy to just write some code and get it out there to see if it worked / what people thought. Can we pick one or the other, though? Moving the discussion back to eff would be simple enough, but maybe there are some good reasons to split it off?

@paf31
Copy link
Contributor

paf31 commented Jun 9, 2017

The original point of this was to be able to emulate traverse_ for any Foldable in Eff, right? If so, I'm not sure this achieves that, since we can't get a safe Iterable from an arbitrary Foldable without either allocating a lot, or using lots of stack.

I'd just like to point out that there is an unsafe option too. However, while unsafeTraverse_ is really unsafe(since it can defer evaluation of effects until evaluation of some part of the result, a la unsafeInterleaveIO), I think unsafeFoldM might actually be okay, since foldl has to produce a single result, and can't defer evaluation in the same way.

@paf31
Copy link
Contributor

paf31 commented Jun 9, 2017

Actually, this does give a way to build a safe traverse_ as well:

traverse_ f fb = unsafeFoldM (\_ a -> void (f a)) unit fb

@paf31
Copy link
Contributor

paf31 commented Jun 9, 2017

Ignore me actually, unsafeFoldM isn't safe after all, because it relies on the values in the Foldable structure being evaluated in the same order they would be mappended together, which is not required by Foldable.

@matthewleon
Copy link
Contributor Author

matthewleon commented Jun 10, 2017

I'd just like to point out that there is an unsafe option too.

This might actually just do the trick in terms of what I'm looking for. It actually looks roughly equivalent to what I was trying to write before, with the additional use of unsafePerformEff. I'll try it out on StrMap and see how it benchmarks. Thanks!

@matthewleon
Copy link
Contributor Author

matthewleon commented Jun 10, 2017

The original point of this was to be able to emulate traverse_ for any Foldable in Eff, right?

If so, I'm not sure this achieves that, since we can't get a safe Iterable from an arbitrary Foldable without either allocating a lot, or using lots of stack.

Well, from an arbitrary Foldable, no. The structures in question would have to write implementations of Iterable — no magic transformation that makes any Foldable an Iterable. So for imperative-style data structures like StrMap you would have to have both fromFoldable, which would either be 1) safe and inefficient or 2) unsafe and more efficient; and fromIterable, which would be both safe and efficient.

I can see how this really makes the API less ergonomic, though. But then, writing code like Array.fromFoldable also seems somehow in violation of the spirit of PureScript – it makes sense for Array, it being such a core data structure, but I'm really not sure it makes sense for other mutable structures.

In any case, I think your unsafeFoldM might be the most elegant way about this.

Edit: Oops! Ignore the above sentence... Elaboration below.

@matthewleon
Copy link
Contributor Author

Ignore me actually, unsafeFoldM isn't safe after all, because it relies on the values in the Foldable structure being evaluated in the same order they would be mappended together, which is not required by Foldable.

Upon rereading your comments, I came to a better understanding of what this implies. Does this not, in turn, imply that fromFoldable in purescript-arrays needs to be changed? https://github.com/purescript/purescript-arrays/blob/v4.0.1/src/Data/Array.js#L47

It seems to me that this implies that we should indeed build an Iterable-style typeclass, and that Array and StrMap should have fromIterable.

@paf31
Copy link
Contributor

paf31 commented Jun 10, 2017 via email

@paf31
Copy link
Contributor

paf31 commented Jun 11, 2017

@matthewleon I reread the paper and started porting it to PureScript. I think it can be very helpful here:

http://try.purescript.org/?gist=e0b868cfceff385409c1a1a4b2917e91&backend=core

Unfortunately, we can't implement Polynomial for Array, at least not nicely.

@matthewleon
Copy link
Contributor Author

@matthewleon I reread the paper and started porting it to PureScript. I think it can be very helpful here:

This is really fascinating, and I'm eager to read the paper and work on this.

@matthewleon
Copy link
Contributor Author

Looking at this code, though, it seems to me that an Iterable instance for a List would be simpler than this. Not to mention for Array. Perhaps the two efforts are complementary, such that this makes it easy to write Iterable instances for more complex structures?

@matthewleon
Copy link
Contributor Author

...Though perhaps what one does for something like StrMap is to have fromArray and fromPolynomial, with fromFoldable for backward compatibility.

Some unfortunate design choices, it seems.

@matthewleon
Copy link
Contributor Author

http://try.purescript.org/?gist=e0b868cfceff385409c1a1a4b2917e91&backend=core

Just a note that McBride calls this Diss... Are you set on Polynomial as the typeclass name? Dissectable seems more descriptive to me.

matthewleon added a commit to matthewleon/purescript-foldable-traversable that referenced this pull request Jun 11, 2017
Based on Phil Freeman's code from this conversation purescript#70 (comment)

In turn based on McBride, 2007. Clowns to the Left of me, Jokers to the
Right: Dissecting Data Structures. http://strictlypositive.org/CJ.pdf
@paf31
Copy link
Contributor

paf31 commented Jun 11, 2017

I'd be fine with Diss or Dissectable but I'd prefer Polynomial.

I agree Iterable seems more immediately useful, but it wouldn't fit into the type class hierarchy in any nice way in my opinion. Polynomial has fewer inhabitants but it seems more principled to me. Every Polynomial is Traversable and Foldable.

@garyb
Copy link
Member

garyb commented Jun 11, 2017

Where does the Polynomial name come from? I must admit I would not expect a class with that name to do the kinds of things we're talking about here. Is it related to the "algebra of ADTs" or something?

@paf31
Copy link
Contributor

paf31 commented Jun 11, 2017

It's from the paper, although while every polynomial function is dissectible, it's not clear that every dissectible functor is polynomial. So perhaps Dissectible is better after all.

@garyb
Copy link
Member

garyb commented Jun 11, 2017

Ohh I see now yeah, polynomial functors. I don't really know what that means still, but will re-read the paper, it's been a while :)

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.

3 participants