0

I'm trying to parse the meaning of the parameter type type _1 >: Char with Int <: AnyVal that is created in the following code (using Scala ammonite repl). I'm defining an array of arrays

  • What is the meaning of with in this context, are we defining a new Char class with the 'traits' of Int?
  • Does the expression >: Char with Int <: AnyVal mean - Any type (_1) that is a supertype of Char with Int but a subtype of AnyVal?
@ val tmix1 = Array(Array[Int](1,2,3), Array[Char]('b','f')) 
tmix1: Array[Array[_1] forSome { type _1 >: Char with Int <: AnyVal }] 
= Array(Array(1, 2, 3), Array('b', 'f'))
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
Nikhil
  • 797
  • 6
  • 12
  • 30
  • 3
    You you have an array of ints and another one of chars, if you create an array that contains both you end up with an array of Arrays of something that is either Char and an Int. So, something useless. If you are learning the language understanding types would be the first step _(btw, stay away of Arrays unless you need them, use Lists or any other real collection)_ – Luis Miguel Mejía Suárez Jul 25 '20 at 18:39
  • thanks yes, this is kind of a toy example, was trying to figure out how (type _1 ) was created – Nikhil Jul 25 '20 at 19:01
  • 3
    Is called an existential type. So it says that it is an **Array[Array[X]]** for some type `X` that is both a super type of `Char with Int` and also a subtype of `AnyVal`. – Luis Miguel Mejía Suárez Jul 25 '20 at 19:07
  • Note that existential types that require the `forSome` syntax will be removed in Scala 3. Only existential types that can be written with the `_` syntax (wildcard types) will be left. – Matthias Berndt Jul 26 '20 at 00:29

1 Answers1

1

Does the expression >: Char with Int <: AnyVal mean - Any type (_1) that is a supertype of Char with Int but a subtype of AnyVal?

Yes, this is correct.

are we defining a new Char class with the 'traits' of Int

We are not defining anything. Are you define a 'class' when you write 'x: Int => String' ? No, it's just type expression. This is a syntax that allows you to express a type. With keyword 'with' you construct a type that is a subtype of Char and subtype of Int. This expression can be used as union type encoding (https://stackoverflow.com/a/6883076/14044371). A union type is a type that combines few types in a single type with logical "Or". It also called "type disjunction". Intuitively you can try to understand this by imagining examples:

// what is the possible supertypes for type 'Char with Int'?
// it is 'Char with Int',  Int, Char, AnyVal, Any 
val x: Char with Int = Char with Int
val a: Int = Char with Int
val b: Char = Char with Int
val c: AnyVal = Char with Int
val d: An y= Char with Int

so T >: Char with Int and T <: AnyVal almost equivalent to Char Or Int

For intuition on Char Or Int I can give you this:

val a: Char Or Int = 1 // is it correct? yes it is
val b: Char Or Int = 'a' // it is correct too
// after that, you can pattern match on such type in a safe manner
def foo(x: Char Or Int) match {
  case Int => ...
  case Char => ...
}

So.

You are correct in your second question.

You are not quite right in the first, because it is not 'class' or 'trait' - it is type expression. This is not intuitive, because you have the same word 'with' like in inheritance of classes and traits. But this word means a little bit different things in different contexts.

This construction is the way to express union type that suits well as a type for the original expression val tmix1 = Array(Array[Int](1,2,3), Array[Char]('b','f'))

Artem Sokolov
  • 810
  • 4
  • 8