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

Add Functor and Applicative #113

Closed
wants to merge 1 commit into from

Conversation

bjorn3
Copy link

@bjorn3 bjorn3 commented Apr 6, 2018

This works on stable, but is ugly


pub trait Applicative<B, F>: Functor<B> + Kind<F> + Sized
where F: Fn(Self::Item) -> B {
fn pure_(Self::Item) -> Self;
Copy link
Collaborator

Choose a reason for hiding this comment

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

yuck on the hack for avoiding the keyword. I might suggest looking to other langauges for naming precedent. (I know a lot of JS libs call this of; I don't know about other languages)

ISTM you are also going to immediately run into problems with type inference when you try to use this method, because its signature does not constrain F.

Copy link
Owner

Choose a reason for hiding this comment

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

I've also seen just being used in the wild.

Copy link
Collaborator

@Centril Centril Apr 9, 2018

Choose a reason for hiding this comment

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

Some "insider info": pure will likely be removed as a keyword soon-ish.

For now, I'm partial to pointed or wrap.

@ExpHP
Copy link
Collaborator

ExpHP commented Apr 6, 2018

I think this really needs examples of usage to demonstrate that it is useful. Or rather, usable. Unsurprisingly, 99% of my own attempts to encode HKT-like abstractions into rust only seemed like a good idea up until the point that I actually tried to use them.

From past experience with type level programming in rust, I doubt it is possible to get very far at all with having the element type be a type argument of Functor. Typically I usually end up running into some thing that I can't write an impl for without the compiler calling it ambiguous (since the compiler doesn't know that T: Functor<A> implies T: !Functor<B>), and the only solution ends up being to turn the element type into an associated type... which obviously defeats the entire purpose of the abstraction.

In summary: I don't think the language is ready for this.

@Centril
Copy link
Collaborator

Centril commented Apr 6, 2018

My view is that we'd like to experiment with this once GATs land, so I agree with @ExpHP.

@Centril
Copy link
Collaborator

Centril commented Apr 7, 2018

Another heads up: given that Rust has affine typing and that we have Fn, FnMut, FnOnce there would either need to be (endo)functors traits for different categories, or we would need some form of ConstraintKinds to generalize over FnWhatever. I recently started an RFC-writing-project to that effect: https://github.com/Centril/rfc-trait-parametric-polymorphism/

See also the following blog post on linear monads in Haskell: https://m0ar.github.io/safe-streaming/2017/07/20/homegrown-linear-monads.html

@lloydmeta
Copy link
Owner

FWIW, I think this is a really cool attempt at implementing HKTs 😎

The Kind<A> with a Make associated type is quite clever and clean!

Just for comparisons' sake:

  1. In Arrow-kt (FP lib for Kotlin), the authors introduced a form of HKT using something like Kind<F,A>, where for a given type constructor, say Option<A>, they create a corresponding private dummy class called ForOption, then make the type Option<A> inherit from Kind<ForOption, A> (more details here)
  2. In Funland/funfix (FP lib for JS), they do something similar w/ HK<F, A> (see here)

I believe both of these are based on the Lightweight HKTs paper that showed how to emulate HKTs in OCaml.

Having said that, I think @ExpHP is right; this would be a lot nicer if you showed usage (e.g. tests or doctests) so it would be easier to see how this works out in practice :)

@ExpHP
Copy link
Collaborator

ExpHP commented Apr 7, 2018

they create a corresponding private dummy class called ForOption

type ForOption = Option<()>;

🦆

@Centril
Copy link
Collaborator

Centril commented Jun 23, 2018

Triage: shall we close this in wait of GATs?

@lloydmeta
Copy link
Owner

Yeah, regrettably, I think it might be best to wait for GATs (which actually shouldn't be all that far off ?? (rust-lang/chalk#116)

@bjorn3
Copy link
Author

bjorn3 commented Jun 23, 2018

No problem

@bjorn3 bjorn3 closed this Jun 23, 2018
@rami3l
Copy link

rami3l commented Sep 14, 2022

GAT is finally here after a long wait! 🍾 Time to reconsider this one?

@ExpHP
Copy link
Collaborator

ExpHP commented Sep 14, 2022

Ah, I see, so they've been stabilized on nightly. That's good news!

I wouldn't exactly say that they're "here" yet (IIRC the ! type has been "stabilized" only to get unstabilized again during beta, multiple times). But now is definitely a good time to start playing around with the feature and helping to put it to the test, and frunk is certainly the kind of crate that could probably stand to benefit from using GATs.

So yeah, if people want to experiment with this and make PRs, I'd say go right ahead.

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