Search code examples
scalaimplicitinfix-notationparametric-polymorphism

Is infix notation allowed in declarations of a parameterized type in Scala?


I have been trying to understand the answers given to the question asked in this post.

The code below reproduces the solution proposed in the accepted answer.

object Finder {
  def find[T <: Node](name: String)(implicit e: T DefaultsTo Node): T = 
    doFind(name).asInstanceOf[T]
}    

sealed class DefaultsTo[A, B]
trait LowPriorityDefaultsTo {
  implicit def overrideDefault[A,B] = new DefaultsTo[A,B]
}
object DefaultsTo extends LowPriorityDefaultsTo {
   implicit def default[B] = new DefaultsTo[B, B]
}

I would understand it if the implicit were defined as

(implicit e:  DefaultsTo[T, Node])

But instead it is defined in something that looks like infix notation. I never knew that a type DefaultsTo[T, Node] could be written as T DefaultsTo Node. Is this what is going on?


Solution

  • But instead it is defined in something that looks like infix notation. I never knew that a type DefaultsTo[T,Node] could be written as "T DefaultsTo Node". Is this what is going on ?

    Yes. The rule is very simple: the type must have precisely 2 parameters. It's primarily intended for types with symbolic names like <:<, but as you can see it works for alphanumeric names as well.

    Scala specification, 3.2.8 Infix Types:

    InfixType     ::=  CompoundType {id [nl] CompoundType}
    

    An infix type T1 op T2 consists of an infix operator op which gets applied to two type operands T1 and T2. The type is equivalent to the type application op[T1,T2]. The infix operator op may be an arbitrary identifier.

    All type infix operators have the same precedence; parentheses have to be used for grouping. The associativity of a type operator is determined as for term operators: type operators ending in a colon ‘:’ are right-associative; all other operators are left-associative.

    In a sequence of consecutive type infix operations t0 op t1 op2 … opn tn, all operators op1,…,opn must have the same associativity. If they are all left-associative, the sequence is interpreted as (…(t0 op1 t1) op2…) opn tn, otherwise it is interpreted as t0 op1 (t1 op2 (…opn tn)…).