mlscript
mlscript copied to clipboard
Wrong mixin typing
mixin EvalNeg {
fun eval(e) = if e is Neg(Lit(d)) then -1
}
//│ mixin EvalNeg() {
//│ fun eval: Neg[Lit] -> -1
//│ }
// * Concise alternative, usign syntax sugar:
mixin EvalNegNeg {
fun eval(e) = if e is Neg(Neg(d)) then 0 else super.eval(e)
}
//│ mixin EvalNegNeg() {
//│ super: {eval: (Neg[nothing] | 'a) -> 'b}
//│ fun eval: (Neg[Neg[anything] | Object & ~#Neg] | Object & 'a & ~#Neg) -> (0 | 'b)
//│ }
module T extends EvalNeg, EvalNegNeg
//│ module T {
//│ fun eval: Neg[Lit] -> (-1 | 0)
//│ }
T.eval(Neg(Neg(0)))
//│ ╔══[ERROR] Type mismatch in application:
//│ ║ l.204: T.eval(Neg(Neg(0)))
//│ ║ ^^^^^^^^^^^^^^^^^^^
//│ ╟── application of type `Neg[?A]` is not an instance of type `Lit`
//│ ║ l.204: T.eval(Neg(Neg(0)))
//│ ║ ^^^^^^
//│ ╟── Note: constraint arises from class pattern:
//│ ║ l.184: fun eval(e) = if e is Neg(Lit(d)) then -1
//│ ║ ^^^
//│ ╟── from field selection:
//│ ║ l.95: class Neg<A>(expr: A)
//│ ║ ^^^^
//│ ╟── Note: type parameter A is defined at:
//│ ║ l.95: class Neg<A>(expr: A)
//│ ╙── ^
//│ -1 | 0 | error
//│ res
//│ = 0
super and this have weird types in mixin EvalNegNeg. The type of eval in EvalNegNeg does not seem to allow any refinement inside Neg, but that still gives Neg[Lit] in the type of the module.