-
Notifications
You must be signed in to change notification settings - Fork 1k
bugfix #2732
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bugfix #2732
Conversation
I think it would be better to provide the definition of def max[A](using Ord[A]): (A, A) => A =
(a1, a2) => if a1 > a2 then a1 else a2 |
@julienrf yeah totally, when I looked at the page I was really lost since I didn't find |
@julienrf This max method doesn't appear to use the Ord instance in any way. Am I missing something? Furthermore, when I try to use this code I get the error: |
|
@julienrf is there a code base with working code for each of these examples? |
@rebekah so the funny thing is that both parts of your question are connected :) But, it is not doing that because that code is also missing an import like: import scala.math.Ordering.Implicits._ So, the lesson of the day is that code examples in docs should be complete and compiled, otherwise they may confuse newcomers reading them; which is exactly the opposite of what a doc should do :) |
@BalmungSan are you saying there would be an implicit class for the ord instance that defined the > method? because if so sure... okay that makes sense. And yes if that is the case it should be clearly communicated... but as it is there are so many levels of assumptions of understanding being made. It would be almost impossible for someone to understand the simple concept of context bounds unless they fully understood type classes and implicit conversion, and could make the assumption that they were being used. I suppose it would be semi-okay if there was a code base to go along with the docs so that if someone wanted to they could refer to the entire context of the method referenced in the docs. But in my opinion, it should just be much simpler, each example should basically stand on it's own. |
I 100% agree with you @rebekah. That page about context bounds explains the syntax that is handled by the compiler, and in some sense we don’t need to know what the definition of Scala 3: trait Ord[A]:
/** @return true if a1 is greater than a2, false otherwise */
def greaterThan(a1: A, a2: A): Boolean
/** @return the maximum value between a1 and a2 */
def max[A](a1: A, a2: A)(using ord: Ord[A]): A =
if ord.greaterThan(a1, a2) then a1 else a2
/** @return the maximum element in a collection */
def maxElement[A](as: List[A])(using ord: Ord[A]): A =
as.reduceLeft(max(_, _)(using ord)) Note that since the def maxElement[A](as: List[A])(using Ord[A]): A =
as.reduceLeft(max(_, _)) Note that since we don’t explicitly use that context parameter, we don’t even need to give it name (that sentence does not apply to Scala 2). In that case, we can shorten the syntax even further by using a context bound: def maxElement[A: Ord](as: List[A]): A =
as.reduceLeft(max(_, _)) And, optionally, even further: def maxElement[A: Ord](as: List[A]): A =
as.reduceLeft(max) In this last form, we replace the function literal Scala 2: trait Ord[A] {
def greaterThan(a1: A, a2: A): Boolean
}
def max[A](a1: A, a2: A)(implicit ord: Ord): A =
if (ord.greaterThan(a1, a2)) a1 else a2
def maxElement[A](as: List[A])(implicit ord: Ord[A]): A =
as.reduceLeft(max(_, _)(ord)) Or: def maxElement[A: Ord](as: List[A]): A =
as.reduceLeft(max(_, _)) Or even: def maxElement[A: Ord](as: List[A]): A =
as.reduceLeft(max[A]) We should also add a note that in practice there is already a trait |
@julienrf Wow, yes that would be fantastic! |
thank you |
Thank you for starting this discussion! |
@julienrf you are welcome! |
The examples didn't make sense to me... so I played with them a bit realized they were broken and talked with @BalmungSan on discord. He suggested this resolution, which seems concise and appropriate. Here is the code in working(and tested) examples: https://github.com/rebekah/scala-3-play/blob/main/src/main/scala/ExploreContextBounds.scala