-
-
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
The K in SemigroupK #1358
Comments
|
I think you're right that the documentation is poorly-worded. As you point out, I'm not convinced that an "F" suffix is any more meaningful than a "K" suffix. I'll have to sleep on it. But thanks for bringing this up! |
I have always thought of "K" in |
@kailuowang A higher-kinded type would something that accepts scala> import cats.Functor
import cats.Functor
scala> :k -v Functor
cats.Functor's kind is X[F[A]]
(* -> *) -> *
This is a type constructor that takes type constructor(s): a higher-kinded type. |
@eed3si9n thanks for the clarification. I wasn't thinking of the specific "higher-kinded type" when I say "higher kinded" (although it definitely looks that way) , I was thinking a kind with higher order, like |
@kailuowang Right, but that's like calling higher-order function (a function that accepts a function) as typelevel Semigroup, or @non:
I think def combineK[A](x: F[A], y: F[A]): F[A] |
I remember having a conversation with @non about this some time back ... I also didn't particularly like I don't remember how the conversation continued from there ... clearly we didn't do anything about it :-) |
Another option might be to use a |
To be fair, there is some lifting going on here that's parametric and cool. But the level of lifting that's happening here is similar to that of liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c We can think of it as a special case where |
I think the "endo" part is key here ... it has to be endo because we (need to) know nothing about the element types, so identity is our only choice. So I think that |
The Scaladoc on SemigroupK (https://github.com/typelevel/cats/blob/v0.7.2/core/src/main/scala/cats/SemigroupK.scala) says:
function as first-order values
I think there's a misunderstanding of the terms. The oft repeated analogy, "kind is to a type, as type is to a value" probably isn't going to clarify it either, but it's a start. Consider the following:
In fp, we can consider functions to be a value, and in Scala, we can store it in a variable:
If we pass in some
Int
, we can derive a proper value e.g.2
. BecauseInt => Int
is one order away from the proper value, it's also called a first-order value. (A function that acceptsInt => Int
and returnsInt
would be a higher-order value, but it doesn't matter here) The important point is thatf
is a value, not a type.type constructor as first-order types
Next, let's consider the type equivalent of the
Int => Int
, which isOption
:Option
accepts a single parameterA
to become a proper type. Just as we consideredf
to be a value, we considerOption
to be a type. It's just first-order kinded.Parameterized types can be called "type constructors" or "type functions", but they themselves are not "kinds."
Semigroup which operates on types
A semigroup that operates on types would be something like a type constructor
=>[_, _]
, since you can take typeA
and typeB
and constructA => B
.Semigroup which operates on kinds
Using the standard notation, the values for kinds are combination of
*
,->
and parenthesis. So, the semigroup that operates on kinds would be something along the lines of_ -> _
, where you pass in kindA
and kindB
and constructA -> B
. This is clearly not whatSemigroupK
is doing.SemigroupF?
I'm not sure what a good alternative would be but I hope I was able to demonstrate that neither "type level" nor "kind level" is appropriate. Maybe we can call it
SemigroupF
for type constructors that take a single operator.The text was updated successfully, but these errors were encountered: