(* recursive signatures and structures *) (* failure tests *) signature Fail1 = rec(Fail: sig type a; type b end) sig end; signature Fail2 = rec(Fail:functor(Y:sig end)->sig end) sig end; signature Fail3 = rec(Fail:sig end) functor(Fail:sig end)->sig end; (* occur check violations *) signature Fail4 = rec(Fail: sig type a; type b end) sig type a = Fail.a type b = Fail.b end; signature Fail5 = rec(Fail: sig type a; type b end) sig type a = Fail.b type b = Fail.a end; (* equality type violations *) signature Fail4 = rec(Fail: sig type a; eqtype b end) sig datatype a = Aa | Ba of Fail.b datatype b = Ab | Bb of Fail.a end; (* success tests *) signature Ok1 = rec(X: sig type a; type b end) sig datatype a = Aa | Ba of X.b datatype b = Ab | Bb of X.a end; signature Ok2 = rec(X: sig type a; type b end) sig datatype a = Aa | Ba of X.b datatype b = Ab | Bb of a end; signature Ok3 = rec(X: sig type a; type b end) sig datatype b = Ab | Bb of X.a datatype a = Aa | Ba of b end; signature OK4 = rec(X: sig eqtype a; eqtype b end) sig datatype a = Aa | Ba of X.b datatype b = Ab | Bb of X.a end; signature Ok5 = rec(X: sig type a; type b end) sig type a type b end; signature Ok6 = rec(X: sig type a = int end) sig type a = int end; signature OK7 = rec(X: sig datatype a = Aa | Ba of b and b = Ab | Bb of a end) sig datatype a = Aa | Ba of X.b datatype b = Ab | Bb of X.a end; signature OK8 = rec(X: sig datatype a = Aa | Ba of b and b = Ab | Bb of a end) sig datatype a = Aa | Ba of b and b = Ab | Bb of a end; structure Ok = rec(X:sig end) struct end; structure Even = rec(X:sig val even:int -> bool end) struct val even = fn x => if x = 0 then true else not(X.even (x-1)) end; val test1 = Even.even 10; structure EvenOdd = rec(X:sig val even:int -> bool val odd:int->bool end) struct val even = fn x => if x = 0 then true else (X.odd (x-1)) val odd = fn x => if x = 0 then false else (X.even (x-1)) end; val test2 = EvenOdd.even 10; val tes3 = EvenOdd.odd 10; signature U = rec(X: sig structure A: sig type a end; structure B: sig type b end end) sig structure A: sig datatype a = Aa | Ba of X.B.b end structure B: sig datatype b = Ab | Bb of X.A.a end end; structure U = rec(X:U) struct structure A = struct datatype a = datatype X.A.a end structure B = struct datatype b = datatype X.B.b end end; signature V = rec(X: sig structure A: sig type a end; structure B: sig type b end end) sig structure A: sig datatype a = Aa | Ba of X.B.b val height: a -> int end; structure B: sig datatype b = Ab | Bb of X.A.a val height: b -> int end end; structure V = rec(X:V) struct structure A = struct datatype a = datatype X.A.a fun height Aa = 0 | height (Ba b) = 1 + X.B.height b end structure B = struct datatype b = datatype X.B.b fun height Ab = 0 | height (Bb a) = 1 + X.A.height a end end; val test4 = V.A.height (V.A.Ba (V.B.Bb V.A.Aa)); val test5 = V.B.height (V.B.Bb(V.A.Ba (V.B.Bb V.A.Aa))); structure V1 = V : V; structure V2 = V :> V; (* Y exports more components than specified in V *) structure Y = rec(X:V) struct structure A = struct datatype a = datatype X.A.a fun height Aa = 0 | height (Ba b) = 1 + X.B.height b val foo = 1 end structure B = struct datatype b = datatype X.B.b fun height Ab = 0 | height (Bb a) = 1 + X.A.height a val bar = true end end; structure Y1 = Y : V; structure Y2 = Y :> V; (* test equivalence of recursive signatures *) val test6 = if true then [structure Y1 as V] else [structure Y1 as V]; (* a subtle case thats fails if we only realize, but don't substitute, type names in the forward spec with their matching type names in the body of the signature *) signature S = rec(X: sig type a end) sig datatype a = C of X.a end; structure A = rec(X:S) struct datatype a = datatype X.a end; structure B = A :> S; structure C = B :> S; signature S = rec(X: sig type ('a,'b) a end) sig datatype ('a,'b) a = C of ('a,'b) X.a | D of 'a | E of 'b end; structure A = rec(X:S) struct datatype a = datatype X.a end; structure B = A :> S; structure C = B :> S; (* one last wild test ... *) signature S = rec(X: sig datatype ('a,'b) a = C of ('a,'b) a | D of 'a | E of 'b end) sig datatype ('a,'b) a = C of ('a,'b) X.a | D of 'a | E of 'b end; structure A = rec(X:S) struct datatype a = datatype X.a end; structure B = A :> S; structure C = B :> S;