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 *Functions traits for all typeclasses, mixed into Prelude. #1814

Open
wants to merge 1 commit into
base: series/8.0.x
Choose a base branch
from

Conversation

hrhino
Copy link
Member

@hrhino hrhino commented May 24, 2018

No exceptions here. I know at least a few people said they would be interested in this.

Methods like pure, which do not allow for F to be inferred from the argument types, also get a *0 variant that uses the "partially applied" hack. A few methods are also exported as natural transformations, named *NT, as I saw fit.

*Functions traits have been set up for all of the subpackages that contain typeclasses, and those now get mixed into Prelude, to keep it shorter.

I have used F and A as type parameters throughout, irrespective of the type parameters on the actual typeclass. We should sort that out.

with ct.InvariantFunctorFunctions
with ct.PhantomFunctions
with ct.TraversableFunctions
extends AnyRef
Copy link
Member

Choose a reason for hiding this comment

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

What's the benefit of extending AnyRef here?

Copy link
Member Author

Choose a reason for hiding this comment

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

If we add a new package that is alphabetically before algebra, we don't need to change the line algebra.AlgebraFunctions to add it here.

package algebra

trait MonoidFunctions {
@inline final def empty[A](implicit A: Monoid[A]): A =
Copy link
Member

Choose a reason for hiding this comment

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

See the build failure :)

Copy link
Member Author

Choose a reason for hiding this comment

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

yep. I'll propose mempty and mappend.

)(implicit F: Profunctor[F]): F[C, D] =
F.dimap(fab)(ca)(bd)

/* TODO: these clash with the bifunctor versions. Decide on a name for them.
Copy link
Member

Choose a reason for hiding this comment

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

contramap / comap
inMap / outMap
mapIn / mapOut

package ct

trait ChoiceFunctions {
@inline final def leftchoice[F[_, _], A, B, C](fab: F[A, B])(implicit F: Choice[F]): F[A \/ C, B \/ C] =
Copy link
Member

Choose a reason for hiding this comment

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

Capital c in choice.

bt: B => T
)(implicit F: Bifunctor[F]): F[S, T] =
F.bimap(fab)(as, bt)
@inline final def lmap[F[_, _], A, B, S](fab: F[A, B])(as: A => S)(implicit F: Bifunctor[F]): F[S, B] =
Copy link
Member

Choose a reason for hiding this comment

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

Another option is to call these firstMap, secondMap after Strong (first/second).

import data.~>

trait ApplicativeFunctions {
@inline final def pure[F[_], A](a: A)(implicit F: Applicative[F]): F[A] =
Copy link
Member

Choose a reason for hiding this comment

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

pure vs point. Decisions, decisions.

have nowhere better to go. This should be made a
superclass of `FooClass`'s companion object, to ensure
that the instances are in the correct implicit scope.
- Note that this means that all typeclass methods must have unique names!
Copy link
Member

Choose a reason for hiding this comment

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

Very important point.

@jdegoes
Copy link
Member

jdegoes commented May 25, 2018

@hrhino Some much needed changes here! 🙏

@hrhino
Copy link
Member Author

hrhino commented May 28, 2018

Sounds good. I'll make those changes and rebase once #1825 lands.

- `FooClass`: The definition of the typeclass.
- `FooSyntax`: Syntax macros for the typeclass methods.
- `FooFunctions`: A trait containing the typeclass's methods, but with
the typeclass as a type parameter.
Copy link
Contributor

Choose a reason for hiding this comment

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

as an implicit parameter?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. I originally had a confusing attempt to say "with the typeclass instance as a type parameter" or something but I trashed it as insufficiently clear.

@jdegoes
Copy link
Member

jdegoes commented May 28, 2018

@hrhino Landed!

@hrhino hrhino added the WIP label May 29, 2018
No exceptions here.

Methods like `pure`, which do not allow for `F` to be inferred from
the argument types, also get a `*0` variant that uses the "partially
applied" hack. A few methods are also exported as natural transformations,
named `*NT`, as I saw fit.

`*Functions` traits have been set up for all of the subpackages that
contain typeclasses, and *those* now get mixed into `Prelude`, to keep
it shorter.

I have used `F` and `A` as type parameters throughout, irrespective
of the type parameters on the actual typeclass. We should sort that out.
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.

4 participants