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

TypeFamlies vs. FunctionalDependencies #77

Open
gelisam opened this issue Feb 2, 2019 · 6 comments
Open

TypeFamlies vs. FunctionalDependencies #77

gelisam opened this issue Feb 2, 2019 · 6 comments

Comments

@gelisam
Copy link
Collaborator

gelisam commented Feb 2, 2019

Part of the Merge yaya into recursion-schemes? thread. Here are the comments from that thread which pertain to the topic.

In the yaya documentation, @sellout says that one advantage of yaya over recursion-schemes is that yaya:

  • uses multi-parameter type classes rather than a type family for the Base functor, because the latter frequently requires constraints in the form of (Recursive t, Base t ~ f), so we prefer Recursive t f.

@phadej responds:

I think the only practical difference is TypeFamlies vs. FunctionalDependencies

  • the difference is visible when you define your own recursion schemes, not when you use them with a > concrete recursive type.
  • if we go for FunctionalDependencies, then the class should have the base functor first, i.e. instance (LisfF a) [a], as then we could conveniently use DeriveAnyClass in deriving clauses.

@gelisam responds:

In (Recursive t, Base t ~ f), is the f a type variable, or does it stand in for a concrete type like ListF a? What would be an example situation in which you've found yourself writing (Recursive t, Base t ~ f)?

One advantage of using a type family is that we can give it a default implementation. In one of my other projects, I am working on deriving associated types using generics, and I think it might make sense one day to use UnRep (NonRecursiveRep (Rep t)), or NonRecursive t for short, as the default for Base t. This would work well with our new generics-based default implementations for embed and project.

I should mention, however, that when implementing recursion schemes Base t is a bit of a mouthful, so it would be helpful if I could write f instead. So maybe I'll start using (Recursive t, Base t ~ f) (with a type variable f, not a concrete type) in the recursion-schemes code :)

@gelisam
Copy link
Collaborator Author

gelisam commented Feb 2, 2019

@phadej responds:

Generic based NonRecursive t derived from Rep t: won't that lose the nice property of readability of ConsF. The Rep of Representable makes sense, as you can use that class without really inspecting the index value. Not the case with recursion-schemes. Am I missing something?

@gelisam responds:

I agree that datatypes generated using generics are unreadable; this is precisely the problem which I want to address in my unrepresentable library.

@phadej
Copy link
Contributor

phadej commented Feb 2, 2019 via email

@gelisam
Copy link
Collaborator Author

gelisam commented Feb 2, 2019

You understand right, and unrepresentable indeed doesn't exist yet, it's a work in progress.

Now that you mention it, since the user would have to write makeUnRep (Proxy @(Base Foo)) anyway, there's no benefit to using Base t = UnRep (...) as the default; we could instead have makeRecursive ''Foo both call makeUnRep and define a custom instance, the default buys nothing.

@Anton-Latukha

This comment was marked as resolved.

@Anton-Latukha

This comment was marked as resolved.

@Anton-Latukha

This comment was marked as resolved.

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

No branches or pull requests

3 participants