1

I am relatively new to the Scala language, and I came across code that looks like this (while reviewing Akka).

val someFlow: Flow[Int, Int, NotUsed] = Flow[Int].reduce[Int](_ + _)

How can I read type annotations like: Flow[Int, Int, NotUsed]?

alt-f4
  • 2,112
  • 17
  • 49
  • 2
    Does this answer your question? [What is a higher kinded type in Scala?](https://stackoverflow.com/questions/6246719/what-is-a-higher-kinded-type-in-scala) – Shankar Shastri Jul 02 '20 at 18:39
  • 1
    @ShankarShastri I'm not sure this has to do with higher kinded types – user Jul 02 '20 at 18:40
  • 2
    Its similar to when you read a `List[Int]` or `Map[String, String]`. Things like lists, maps are genralized over the type parameter which enables you to just define a `List[A]` once and then use that to construct a `List[Int]`, `List[String]` etc by filling in that type parameter `A`. In a sense you can think of `List` as a type constructor (called as `kinds` in Scala) which gives you the types `List[Int]`, `List[String]` etc when you provide the type argument. Then come the `higer kinded type` which take a `kind` as parameter such as `Functor[F[_]]`, `Monad[F[_]]`. – sarveshseri Jul 02 '20 at 19:51

1 Answers1

3

Consider a value-level function application

((x: Int) => List(x))(42)

where value-lambda (x: Int) => List(x) is applied to value argument 42.

Consider a type-level function application

([X] =>> List[X])[Int]

where type-lambda [X] =>> List[X] is applied to type argument Int.

Now compare the two in

scala> val v: ([X] =>> List[X])[Int] = ((x: Int) => List(x))(42)
val v: List[Int] = List(42)

We see that a type lambda or type constructor constructs a proper type List[Int] which accommodates a value List(42) constructed by a value lambda or value constructor.

Note the similarity between => and =>>. Now =>> syntax is only available in Dotty (Scala 3) which brings type lambdas, however I believe it is already a helpful device to grok what types such as Flow[Int, Int, NotUsed] really are

([In, Out, Mat] =>> Flow[In, Out, Mat])[Int, Int, NotUsed]

These are the facilities to support the techniques of polymorphism which allows us to think in ever higher levels of abstraction. For example, if f takes a box of chocolates

def f(v: Box[Chocolate] = ???

then g takes a box of something A

def g[A](v: Box[A]) = ???

and we can go even higher where h takes some kind of container F of something A

def h[F[_], A](v: F[A]) = ???

This last form of polymorphism is known as type constructor polymorphism and is what separates Scala from many other languages which stop at the box of something.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
  • 3
    In some branches of mathematics, functions are called "value constructors". If you think about them like that, the analogy to type constructors becomes really obvious. – Jörg W Mittag Jul 02 '20 at 21:00