

In the following code snippet, I define a Function1 Functor:
implicit def Function1Functor[R]: Functor[({type l[a]=(R) => a})#l] = new Functor[({type l[a]=(R) => a})#l] {
def fmap[A, B](r: R => A, f: A => B) = r andThen f
}
1. But why is that signature ({type l[a]=(R) => a})#l like that? how to interpret that?
2. I could now randomly pick any type and qualify that as a Functor. For example., case class SomeRandomType[A] (param: A) // this does not know about the fact that it is going to be a Functor soon
val someRandomTypeFunctor = new Functor[SomeRandomType] { def map[A, B](fa: SomeRandomType[A])(f: A => B): SomeRandomType[B] = SomeRandomType(f(fa.param)) } So this to me is a Typeclass definition. Is that correct?

You received this message because you are subscribed to the Google Groups "scalauser" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.


W dniu środa, 19 kwietnia 2017 09:16:59 UTC+2 użytkownik Joe San napisał: In the following code snippet, I define a Function1 Functor:
implicit def Function1Functor[R]: Functor[({type l[a]=(R) => a})#l] = new Functor[({type l[a]=(R) => a})#l] {
def fmap[A, B](r: R => A, f: A => B) = r andThen f
}
1. But why is that signature ({type l[a]=(R) => a})#l like that? how to interpret that?
This is called a type lambda. You can think about it as an anonymous function in the domain of types. It is typically used in Scala to partially apply a type constructor, ie. convert a type constructor that takes more parameters (Function1[A,+R] in your case) to a type constructor that takes less parameters (Function1Functor[A] respectively). Google it up, there are some really good articles about it out there. 2. I could now randomly pick any type and qualify that as a Functor. For example.,
Well, for any type constructor F[_] an instance of Functor[F] can be summoned, using Yoneda lemma. But this is advanced categorytheoretical wizardry, on the far boundary of my expertise. There are also materials and talks out there. Google up "free monads", because deriving Functors for arbitrary F[_] is an essential step in this technique. case class SomeRandomType[A] (param: A) // this does not know about the fact that it is going to be a Functor soon
val someRandomTypeFunctor = new Functor[SomeRandomType] { def map[A, B](fa: SomeRandomType[A])(f: A => B): SomeRandomType[B] = SomeRandomType(f(fa.param)) } So this to me is a Typeclass definition. Is that correct?
It appears to be, yes. Unfortunately I don't know if it's consistent, or the correct alignment of types there is a mere coincidence ;)
cheers, Rafał

You received this message because you are subscribed to the Google Groups "scalauser" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.


Op woensdag 19 april 2017 09:16:59 UTC+2 schreef Joe San: In the following code snippet, I define a Function1 Functor:
implicit def Function1Functor[R]: Functor[({type l[a]=(R) => a})#l] = new Functor[({type l[a]=(R) => a})#l] {
def fmap[A, B](r: R => A, f: A => B) = r andThen f
}
1. But why is that signature ({type l[a]=(R) => a})#l like that? how to interpret that?
Functor is defined like this (more or less): trait Functor[F[_]]. This means that it accepts a type constructor of arity 1. Function1 is defined like this: trait Function1[A,+B]. So Function1 is a type constructor of arity 2. If you write a Functor for List (arity 1) you can just say Functor[List] and you're done. But Functor[Function1] is impossible. So to create a Functor for a Function1 you have to supply 1 type argument to Function1 and leave 1 parameter open, or in other words partially apply the Function1 type constructor. Scala doesn't have special syntax for partially applying type constructors, so you have to do it with ({ type Lambda[x] = Function1[SomeType,x] })#Lambda. How this works is that you create a structural type that contains a type alias called Lambda which is a type constructor of arity 1. Then you use the # operator on that structural type to extract the Lambda type constructor; this is called type projection. 2. I could now randomly pick any type and qualify that as a Functor. For example., case class SomeRandomType[A] (param: A) // this does not know about the fact that it is going to be a Functor soon
val someRandomTypeFunctor = new Functor[SomeRandomType] { def map[A, B](fa: SomeRandomType[A])(f: A => B): SomeRandomType[B] = SomeRandomType(f(fa.param)) } So this to me is a Typeclass definition. Is that correct?

You received this message because you are subscribed to the Google Groups "scalauser" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.


There is a compiler plugin (https://github.com/non/kindprojector) which adds special syntax for this purpose. It enables you to write Functor[R => ?]. Op woensdag 19 april 2017 11:08:17 UTC+2 schreef JasperM: Op woensdag 19 april 2017 09:16:59 UTC+2 schreef Joe San: In the following code snippet, I define a Function1 Functor:
implicit def Function1Functor[R]: Functor[({type l[a]=(R) => a})#l] = new Functor[({type l[a]=(R) => a})#l] {
def fmap[A, B](r: R => A, f: A => B) = r andThen f
}
1. But why is that signature ({type l[a]=(R) => a})#l like that? how to interpret that?
Functor is defined like this (more or less): trait Functor[F[_]]. This means that it accepts a type constructor of arity 1. Function1 is defined like this: trait Function1[A,+B]. So Function1 is a type constructor of arity 2. If you write a Functor for List (arity 1) you can just say Functor[List] and you're done. But Functor[Function1] is impossible. So to create a Functor for a Function1 you have to supply 1 type argument to Function1 and leave 1 parameter open, or in other words partially apply the Function1 type constructor. Scala doesn't have special syntax for partially applying type constructors, so you have to do it with ({ type Lambda[x] = Function1[SomeType,x] })#Lambda. How this works is that you create a structural type that contains a type alias called Lambda which is a type constructor of arity 1. Then you use the # operator on that structural type to extract the Lambda type constructor; this is called type projection. 2. I could now randomly pick any type and qualify that as a Functor. For example., case class SomeRandomType[A] (param: A) // this does not know about the fact that it is going to be a Functor soon
val someRandomTypeFunctor = new Functor[SomeRandomType] { def map[A, B](fa: SomeRandomType[A])(f: A => B): SomeRandomType[B] = SomeRandomType(f(fa.param)) } So this to me is a Typeclass definition. Is that correct?

You received this message because you are subscribed to the Google Groups "scalauser" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.


On 4/19/17 3:16 AM, Joe San wrote:
1. But why is that signature ({type
l[a]=(R)
=>
a})#l like
that? how to interpret that?
Given
type l[a]=(R) => a
then
l
Or, alternatively, you can think of it as meaning
l
where
type l[a]=(R) => a
Jasper has described the mechanism by which this is implemented.
2. I could now randomly pick any type and qualify that as a
Functor.
Not any type, but lots of them, sure. Including the one
below.
For example.,
case class SomeRandomType[A] (param: A) // this does
not know about the fact that it is going to be a Functor soon
val someRandomTypeFunctor = new
Functor[SomeRandomType] {
def map[A, B](fa: SomeRandomType[A])(f: A => B):
SomeRandomType[B] =
SomeRandomType(f(fa.param))
}
So this to me is a Typeclass definition. Is that correct?
Yep.

Stephen Compall

You received this message because you are subscribed to the Google Groups "scalauser" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

