From 40ee866e90e7dc76bba86d73364dcfc9af2649a4 Mon Sep 17 00:00:00 2001 From: Miles Yucht Date: Sun, 26 Feb 2023 12:39:53 +0100 Subject: [PATCH] Correct example of expanded using clauses The example of how using clauses are expanded by the compiler is not correct. `descending` accepts a context parameter for an ordering of the elements of the list, not an ordering of the list itself. I just tested this out in the repl: ```scala scala> trait Ord[T]: | def compare(x: T, y: T): Int | extension (x: T) | def < (y: T) = compare(x, y) < 0 | def > (y: T) = compare(x, y) > 0 | // defined trait Ord scala> def max[T](x: T, y: T)(using ord: Ord[T]): T = | if ord.compare(x, y) < 0 then y else x | def max[T](x: T, y: T)(using ord: Ord[T]): T scala> def maximum[T](xs: List[T])(using Ord[T]): T = | xs.reduceLeft(max) | def maximum[T](xs: List[T])(using x$2: Ord[T]): T scala> given intOrd: Ord[Int] with | def compare(x: Int, y: Int) = | if x < y then -1 else if x > y then +1 else 0 | | given listOrd[T](using ord: Ord[T]): Ord[List[T]] with | | def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match | case (Nil, Nil) => 0 | case (Nil, _) => -1 | case (_, Nil) => +1 | case (x :: xs1, y :: ys1) => | val fst = ord.compare(x, y) | if fst != 0 then fst else compare(xs1, ys1) | // defined object intOrd // defined class listOrd def listOrd[T](using ord: Ord[T]): listOrd[T] scala> val xs = List(1, 10, 2, 9, 3, 8, 4, 7, 5, 6) val xs: List[Int] = List(1, 10, 2, 9, 3, 8, 4, 7, 5, 6) scala> maximum(xs) val res0: Int = 10 scala> def descending[T](using asc: Ord[T]): Ord[T] = new Ord[T]: | def compare(x: T, y: T) = asc.compare(y, x) | | def minimum[T](xs: List[T])(using Ord[T]) = | maximum(xs)(using descending) | def descending[T](using asc: Ord[T]): Ord[T] def minimum[T](xs: List[T])(using x$2: Ord[T]): T scala> maximum(xs)(using descending) val res1: Int = 1 scala> maximum(xs)(using descending(using intOrd)) val res2: Int = 1 scala> maximum(xs)(using descending(using listOrd)) -- [E007] Type Mismatch Error: ------------------------------------------------- 1 |maximum(xs)(using descending(using listOrd)) | ^^^^^^^ | Found: listOrd[Int] | Required: Ord[Int] | | longer explanation available when compiling with `-explain` 1 error found ``` --- docs/_docs/reference/contextual/using-clauses.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/_docs/reference/contextual/using-clauses.md b/docs/_docs/reference/contextual/using-clauses.md index 8f410ebc026e..f590cc2e7492 100644 --- a/docs/_docs/reference/contextual/using-clauses.md +++ b/docs/_docs/reference/contextual/using-clauses.md @@ -100,8 +100,7 @@ With this setup, the following calls are all well-formed, and they all normalize ```scala minimum(xs) maximum(xs)(using descending) -maximum(xs)(using descending(using listOrd)) -maximum(xs)(using descending(using listOrd(using intOrd))) +maximum(xs)(using descending(using intOrd)) ``` ## Multiple `using` Clauses