mlscript icon indicating copy to clipboard operation
mlscript copied to clipboard

Wrong mixin typing

Open andongfan opened this issue 2 years ago • 0 comments

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.

andongfan avatar Nov 23 '23 05:11 andongfan