Quantcast

Function Functors Definition

Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Function Functors Definition

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?

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 "scala-user" 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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Function Functors Definition

Rafał Krzewski
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 category-theoretical 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 "scala-user" 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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Function Functors Definition

Jasper-M
In reply to this post by Joe San


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 "scala-user" 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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Function Functors Definition

Jasper-M
There is a compiler plugin (https://github.com/non/kind-projector) 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 Jasper-M:


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 "scala-user" 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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Function Functors Definition

Stephen Compall-3
In reply to this post by Joe San

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 "scala-user" 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.
Loading...