-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Inject for either #1600
Inject for either #1600
Conversation
3848ed5
to
1b61293
Compare
I'll rebase/finish this after settling #1725 |
9146b2b
to
b070c71
Compare
b070c71
to
5c51adf
Compare
Codecov Report
@@ Coverage Diff @@
## master #1600 +/- ##
==========================================
+ Coverage 93.99% 94.02% +0.03%
==========================================
Files 253 256 +3
Lines 4180 4202 +22
Branches 155 90 -65
==========================================
+ Hits 3929 3951 +22
Misses 251 251
Continue to review full report at Codecov.
|
|
||
def prj: B => Option[A] | ||
|
||
def apply(a: A): B = inj(a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we make these two final as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
5c51adf
to
b56e92a
Compare
/** | ||
* Inject is a type class to inject a value of type `A` into a | ||
* coproduct of types `B` when `A :≺: B`. The coproduct `B` is | ||
* modelled with `Either`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's true that it is the original incentive for introducing this class, but now that we made a type class, this is just one specific usage/instances of Inject
and InjectK
right?
We could have an Inject
between A
and List[A]
or Int
and Double
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's correct. I suppose it could be reworded to indicate that that's just the default behavior?
Inject is a type class to inject a value of type `A` into another type `B`.
The default instances provided by cats injects `A` into coproduct of types
`B` when `A :≺: B`. The coproduct `B` is modelled with `Either`.
Also in this explanation, :≺:
is used in a conceptual sense. :≺:
exists as a type alias for InjectK
which could be confusing. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding of the Inject
type class is that it represents an injective function between type A
and B
. If we treat types as sets, and a function between the two types are just pairs of elements in the two sets A
and B
. Each pair has an "input" element in set A
and an "output" element of B
. For an injective function, for every element in A
there is exactly one pair. And for every element in B
there is either one pair or no pair at all.
A total pure scala function is an injective function, but it only specifies pairs for all elements in A
, i.e. given any A
you can get a B
. It doesn't specify pairs for elements in B
, this Inject
type class does that through proj
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed with @kailuowang; I don't think this is particularly informative as to what Inject
does, especially because we're likely going to provide these other instances in the future from cats. I'd pick something like:
Inject is a type class providing an injection f
from type A
into another type B
.
An injection is a function which does not destroy any information, and thus for every b: B
there is at most one a: A
such that f(a) = b
.
Because of this all injections admit partial inverses, functions B => Option[A]
, which pair a value b: B
with the single value a: A
that f
sends to b
if it exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@edmundnoble I like your explanation. I tweaked it a tad-- how about:
/**
* Inject is a type class providing an injection from type `A` into
* another type `B`. An injection is a function `inj` which does not
* destroy any information: for every `b: B` there is at most one
* `a: A` such that `inj(a) = b`.
*
* Because of this all injections admit partial inverses `prj` which
* pair a value `b: B` back with a single value `a: A`.
*
* @since 1.0
* @note Prior to cats 1.0, Inject handled injection for type
* constructors. For injection of type constructors, use [[InjectK]].
*
* @see [[InjectK]] for injection for [[cats.data.EitherK]]
*/
abstract class Inject[A, B] // ...
I'll give the same treatment to InjectK
once proper doc is decided.
b56e92a
to
521a0c4
Compare
merge with 2 sign-offs |
Re-introduces
Inject
, but forEither
. I also went ahead and tried to document bothInject
andInjectK
.Todo:
Associated issue: #1599