Most of the info is here :
https://github.com/max-l/Squeryl/commit/ce94283fd56bb7f9a322ca46bd9e6486df4cc574#L6L397
Basically what this code tries to do (appart from creation the proper AST which is the easy part)
is to make sure that the return type is correct, for ex.:
in an expression such as :
caseWhen(<condition1>, <valueExpressionA1>)
when(<condition2>, <valueExpressionA2>)
otherwise(<valueExpressionA3>)
If valueExpressionA1, valueExpressionA2, valueExpressionA3 are respectively
Int, Float and Double, the type of the result needs to be Double,
if it is Int, Float and Option[Float], then the return type will be Option[Float].
Such is the intent of this method :
+ CaseWhenNumericalElement[A](
...
+ def when[B,C](condition: LogicalBoolean, then: NumericalExpression[B])(implicit ev: BinaryAMSOp[A,B] <%< NumericalExpression[C]) = {
+ val bo = new BinaryAMSOp[A,B](this.then, then,"!CaseWhen!") : NumericalExpression[C]
+ new CaseWhenNumericalElement[C](Some(condition), bo, Some(this))
+ }
if there exist an implicit conv. for creating a BinaryAMSOp[A,B] (the intermediate conversion for binary addition multiplication
subtraction, because a chain of case/when behave like a chain of Additions at the type level).
Note that the scheme prohibits mixing numericals with non numericals, which is a conscious decision.
This is the wall that I ran into at the time :
http://scala-programming-language.1934581.n4.nabble.com/Question-on-lt-lt-can-it-be-done-td2277987.html
ML