Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any comprehensive tutorial on how to use this kind of structural typing?

As seen here, map is defined

in a slightly funky way

For completeness' sake, here's the code:

implicit def FunctionFunctor[R] = new Functor[({type l[a] = R=>a})#l] {
  def map[A, B](fa: R => A)(f: A => B) : R => B = (x => f(fa(x)))
}

More concretely - new Functor[({type l[a] = R=>a})#l]

I do think I know what's going on, but can't say honestly that I fully understand the concept. And since there is no any hint, I can't event google the term (I simply don't know that to google). Does some tutorial (or review, or whatever) exist where this is explained with a better level of detalization? I'd appreciate even more is someone could explain it right here in the answers.

like image 973
tkroman Avatar asked Jul 22 '14 20:07

tkroman


People also ask

What is structural typing in programming?

In structural typing, an element is considered to be compatible with another if, for each feature within the second element's type, a corresponding and identical feature exists in the first element's type. Some languages may differ on the details, such as whether the features must match in name.

What is structural typing TypeScript?

TypeScript is a Structural Type System. A structural type system means that when comparing types, TypeScript only takes into account the members on the type. This is in contrast to nominal type systems, where you could create two types but could not assign them to each other.

Does Java have structural typing?

Languages like C++, Java, and Swift have primarily nominal type systems.

Does Scala have duck typing?

Gettings Our Ducks in a Row Fortunately, Scala allows us to write idiomatic code to achieve the same results as duck typing.


1 Answers

This is a special case of structural typing but called a 'type lambda', if you search for type lambda scala google will give you some results.

In short, it's used in a similar fashion as partially applied functions.

def x(a:Int, b:Int):Int = a * b
val x10 = x(10, _:Int)
x10(2) // 2

An example with types.

type IntEither[B] = Either[Int, B]
val y:IntEither[String] // Either[Int, String]

In some cases methods or classes expect a type with a single parameter

class Test[F[_]]

You can not give the Test class an Either because Test expects a type with 1 parameter and Either has 2. In order to be able to pass in an Either we can partially apply it

type X[B] = Either[Int, B]
new Test[X]

An alternative way of writing it is like this:

type X = {
  type T[x] = Either[Int, x]
}

new Test[X#T]

Instead of creating a type alias, we can also define the X type anonymously

new Test[({type T[x] = Either[Int, x]})#T]

These all give you an instance of type Test[Either[Int, x]].


Edit

Your example could look like this:

type PartiallyTypedFunction[R] = {
  type T[x] = R => x 
}

implicit def FunctionFunctor[R] =
  new Functor[PartiallyTypedFunction[R]#T] {
    def map[A, B](fa: R => A)(f: A => B): R => B = (x => f(fa(x)))
  }
like image 143
EECOLOR Avatar answered Nov 03 '22 11:11

EECOLOR