2

The following is from a ScalaZ document when I am learning about subtype polymorph in Scala.

scala> trait Plus[A] {
         def plus(a2: A): A
       }
defined trait Plus

scala> def plus[A <: Plus[A]](a1: A, a2: A): A = a1.plus(a2)
plus: [A <: Plus[A]](a1: A, a2: A)A

I do not follow the part A <: Plus[A]. What is the intuition behind? In particular, the same A appears there, making me quite confused.

zell
  • 9,830
  • 10
  • 62
  • 115
  • 1
    In more idiomatic Scala, I think this would be written `trait Plus[A] { def plus(x: A, y: A): A }; def plus[A](x: A, y: A)(implicit p: Plus[A]) { p.plus(x, y) }` (except there would be more helper definitions). You don't have to understand what I just wrote, but I would still imagine the code you've posted to be somewhat rare. – HTNW Sep 16 '19 at 04:37
  • 3
    @HTNW Even with the much I also like FP. I would not call **typeclasses** more _idiomatic_ than **subtyping** _(even given I prefer the former)_. Also, I do not find nothing rare about the code that OP posted, it is just subtyping + f-bounded polymorphism, that is somewhat common – Luis Miguel Mejía Suárez Sep 16 '19 at 05:03

1 Answers1

4

A <: Plus[A] is called F-bounded type. Here is good example of what it is useful for.

In your example it means that each A must implement Plus, so that each A can add itself to any other A. You need type A in Plus in order to make this trait polymorphic in type A.

In general, your def plus [A <: Plus[A]] is polymorphic by subtype, because you can call it with different implementations sub-typing trait Plus

Bogdan Vakulenko
  • 3,380
  • 1
  • 10
  • 25
  • 3
    It would be useful to add that `<:` is also a **type bound**. In general `A <: B` just demands that the method / class can be used with any type _(A)_ that is a subtype of B. Just that in this particular case, it was required to be an **F-Bounded**. – Luis Miguel Mejía Suárez Sep 16 '19 at 04:58