module A { datatype Explicit = Nil | Cons(set, Explicit); datatype Inferred = Nil | Cons(set, Inferred); class C { method M(x: Explicit) method N(x: Inferred) } } module B refines A { class C { method M(x: Explicit) method N(x: Inferred) } } // ---------------------------- module C { type X(==); type Y(==); } module D refines C { class X { } datatype Y = Red | Green | Blue; } module E refines C { codatatype X = Next(int, X); // error: X requires equality and codatatypes don't got it datatype Y = Nil | Something(Z) | More(Y, Y); // error: Y does not support equality codatatype Z = Red | Green(X) | Blue; } module F refines C { datatype X = Nil | Cons(T, X); // error: not allowed to add a type parameter to type X class Y { } // error: not allowed to add a type parameter to type Y } module G refines C { datatype X = Nil | Next(Z, X); // error: X does not support equality datatype Y = Nil | Something(Z) | More(Y, Y); // error: Y does not support equality codatatype Z = Red | Green | Blue; } // ---------------------------- module H { datatype Dt = Nil | Cons(T, Dt); datatype BulkyList = Nothing | Wrapper(T, BulkyListAux); datatype BulkyListAux = Kons(set, BulkyListAuxAux); datatype BulkyListAuxAux = GoBack(BulkyList); codatatype Stream = Next(head: T, tail: Stream); method M(x: T) { } function method F(x: BulkyList, y: BulkyList): int { if x == y then 5 else 7 } // this equality is allowed function method G(x: Dt, y: Dt): int { if x == y then 5 else 7 } // error: the equality is not allowed, because Dt may not support equality function method G'(x: Dt, y: Dt): int { if x == y then 5 else 7 } // fine method Caller0(b: BulkyList, y: int) { match (b) { case Nothing => case Wrapper(t, bla) => var u; if (y < 100) { u := t; } // The following call is allowed, because it will be inferred that // 'u' is of a type that supports equality M(u); } } method Caller1(d: Dt) { match (d) { case Nil => case Cons(t, rest) => M(t); // error: t may be of a type that does not support equality } } method Caller2(co: Stream) { var d := Cons(co, Nil); Caller1(d); // case in point for the error in Caller1 } }