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

Class-based algebras. #13

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

Class-based algebras. #13

wants to merge 8 commits into from

Conversation

sellout
Copy link
Contributor

@sellout sellout commented Mar 12, 2016

This adds some functionality, but also generalizes things pretty extremely.

I took the approach suggested by @wemrysi and defined a class for the most generic {co}algebras, then used type alias for the more constrained ones. I ended up having to explicitly define a subclass for GCoalgebra, because scalac doesn’t like Id[Id[_]] showing up in types.

We now

  • can .attribute any algebra;
  • can .generalize, .generalizeElgot, and .generalizeM any {co}algebra (that doesn’t already have a functor in the generalizing position);
  • have transApoM (for @drostron);
  • have totally general {co}algebras (GElgot*lgebraM);
  • no longer have to define an implicit for each new functor; and
  • have some additional docs.

I have a couple issues with this – having to explicitly call an implicit conversion in some cases and still not being able to get .zip from implicit conversions.

Also, there are more changes to be made to make the types consistent. But, in general, algebras implicitly convert to/from functions fine, while coalgebras, maybe not so much.

@codecov-io
Copy link

Current coverage is 63.15%

Merging #13 into master will decrease coverage by -2.08% as of 500dfe7

@@            master     #13   diff @@
======================================
  Files           17      14     -3
  Stmts          233     247    +14
  Branches         4       4       
  Methods          0       0       
======================================
+ Hit            152     156     +4
  Partial          0       0       
- Missed          81      91    +10

Review entire Coverage Diff as of 500dfe7

Powered by Codecov. Updated on successful CI builds.

def apply(v1: E[F[G[A]]]) = f(v1)
}
object GElgotAlgebraM {
implicit def zip[E[_]: Functor, G[_]: Functor, M[_]: Applicative, F[_]: Functor]:
Copy link
Contributor

Choose a reason for hiding this comment

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

There is the potential here for zip to get shadowed by a local definition since it's such a common identifier, so it might make sense to call this method gElgotAlgebraMZip or similar.

On further inspection maybe this was intentional.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not intentional as such … but I have never managed to have this implicit found, so I always have to explicitly refer to GElgotAlgebraM.zip.zip, with some type parameters thrown in to get it to work. So the short name seemed useful.

I would be happy to give it a long name if it means that implicit search will find it, but no luck so far.

Copy link
Contributor

Choose a reason for hiding this comment

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

You could also add zip as a method on GElgotAlgebraM (and then just delegate to it here) which would eliminate the need to explicitly refer to this instance when you aren't working abstractly with some F[_]: Zip.

@@ -312,15 +391,23 @@ package object matryoshka extends CofreeInstances with FreeInstances {
CorecursiveOps[T, F] =
new CorecursiveOps[T, F](f)

implicit def ToAlgebraOps[F[_], A](a: Algebra[F, A]): AlgebraOps[F, A] =
new AlgebraOps[F, A](a)
implicit sealed class CofreeOps[F[_], A](self: Cofree[F, A]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could make this and FreeOps final classes.

@wemrysi
Copy link
Contributor

wemrysi commented Mar 21, 2016

@sellout 👍 (apologies for the delay, I thought I had confirmed this already!).

@wemrysi
Copy link
Contributor

wemrysi commented Mar 1, 2017

@sellout So we're approaching the first anniversary of this PR, not sure if that makes it easier or harder to close ;)

@sellout
Copy link
Contributor Author

sellout commented Mar 1, 2017

Hah, yes – I was about to go over this and the even older PR that’s still open. See if there’s anything worth salvaging – at least open some issues.

@paulp
Copy link
Contributor

paulp commented Mar 9, 2017

I would love to see class based algebras, including composable Bialgebras (and Bimonads) as first-class entities.

I think the smart move would be to reduce the function and concept footprint of the current library and create multiple ways to assemble the arguments to a smaller number of functions. A tiny handful of morphisms dominate all uses, and the details of inference and implicits dominate the ergonomics of using the library. If you look at a generalized hylomorphism from different perspectives (input-centric, algebra-centric, monad-centric, adjoint-fold-centric ...) different interfaces emerge. And being explicit about partial application is a tremendous boon for usage because you can lose a lot of the type lambdas and work with single argument type constructors.

@wemrysi wemrysi removed their assignment Nov 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants