Hello everyone ,
I am using Scala 3.1.0 I got from Homebrew, with JDK 11:
➜ scala
Welcome to Scala 3.1.0 (11.0.13, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala>
I am on Chapter 18 “Type Parameterization” of the 5th edition, at the end of the Chapter on page 314-315. There is the example of the orderedMergeSort
function:
def orderedMergeSort[T <: Ordered[T]](xs: List[T]): List[T] =
def merge(xs: List[T], ys: List[T]): List[T] =
(xs, ys) match
case (Nil, _) => ys
case (_, Nil) => xs
case (x :: xs1, y :: ys1) =>
if x < y then x :: merge(xs1, ys)
else y :: merge(xs, ys1)
val n = xs.length / 2
if n == 0 then xs
else
val (ys, zs) = xs.splitAt(n)
merge(orderedMergeSort(ys), orderedMergeSort(zs))
Then there is an example showing why this won’t work with Int
because Int
is not a subtype of Ordered[Int]
. The book says:
scala> val wontCompile = orderedMergeSort(List(3, 2, 1))
<console>:5: error: inferred type arguments [Int] do
not conform to method orderedMergeSort's type
parameter bounds [T <: Ordered[T]]
val wontCompile = orderedMergeSort(List(3, 2, 1))
ˆ
However I get the following from the REPL:
click to expand
scala> val wontCompile = orderedMergeSort(List(3,2,1))
-- Error:
1 |val wontCompile = orderedMergeSort(List(3,2,1))
| ^
|Found: (3 : Int)
|Required: Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[Ordered[Ordered[Ordered[...[...]]]]]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
|]
|
|One of the following imports might fix the problem:
|
| import math.BigDecimal.int2bigDecimal
| import math.BigInt.int2bigInt
|
-- Error:
1 |val wontCompile = orderedMergeSort(List(3,2,1))
| ^
|Found: (2 : Int)
|Required: Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[Ordered[Ordered[Ordered[...[...]]]]]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
|]
|
|One of the following imports might fix the problem:
|
| import math.BigDecimal.int2bigDecimal
| import math.BigInt.int2bigInt
|
-- Error:
1 |val wontCompile = orderedMergeSort(List(3,2,1))
| ^
|Found: (1 : Int)
|Required: Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[
| Ordered[Ordered[Ordered[Ordered[...[...]]]]]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
| ]
|]
|
|One of the following imports might fix the problem:
|
| import math.BigDecimal.int2bigDecimal
| import math.BigInt.int2bigInt
|
If I supply the type parameter [Int]
then it gives a message that is closer to the book (but still different):
scala> val wontCompile = orderedMergeSort[Int](List(3,2,1))
-- Error:
1 |val wontCompile = orderedMergeSort[Int](List(3,2,1))
| ^
|Type argument Int does not conform to upper bound Ordered[Int]
I wonder if this is an issue with the compiler, or the book, or have things changed since the book was written. Is there an explanation for the nested recursive Ordered[...]
s going on? I suppose the type inference is stuck in some loop, then stops at some point?