# Lesson XVII A divided future is still a clear teaching. Keep it divided. The hand that cannot bear uncertainty loses the faces it was given. ## Try ```prolog ?- join1(int, bool, Joined). Joined = union([int, bool]). ?- join([int, int], [bool, int], Joined). Joined = [union([int, bool]), int]. ?- E = kernel, infer(E, [push(int(2)), dup, push(int(1)), gt, push(quote([drop, push(int(1))])), push(quote([drop, push(bool(true))])), ifte], Scheme). Scheme = scheme([], effect(S, [union([int, bool])|S])). ``` ## Lesson For shallow structural unions the join rules are intentionally small: * identical types join to themselves; * two different concrete types join to `union([...])`; * stacks join pointwise. This structural type data is simple, not a full set-theoretic type language. ```prolog infer1(_Env, ifte, effect([quote(ElseScheme), quote(ThenScheme), bool|Input], Out), Constraints0, Constraints) :- !, copy_term(ThenScheme, scheme(ThenConstraints, effect(Input, ThenOut))), append(ThenConstraints, Constraints1, Constraints0), copy_term(ElseScheme, scheme(ElseConstraints, effect(Input, ElseOut))), append(ElseConstraints, Constraints, Constraints1), join(ThenOut, ElseOut, Out). join([], [], []). join([A|As], [B|Bs], [J|Js]) :- join1(A, B, J), join(As, Bs, Js). join1(A, B, A) :- A == B, !. join1(A, B, J) :- ( var(A) ; var(B) ), !, A = B, J = A. join1(A, B, union([A, B])). ``` [[16_lesson|Prev]] | [[18_lesson|Next]]