1     private@
2     
3     type A =
4         | t@ u32
5         | t@ String
6     
7     do
8         let n1 : u32 = 1
9         let n2 = "1"
10        let a1 = n1.as<A>
11        let a2 = n2.as<A>
12    
13        let f (a : A) = case a of
14            x : u32 -> x.to_string
15            is String -> a
16    
17        let s1 = f a1
18        let s2 = f a2
19        assert s1 == "1" && s2 == "1"
20    
21    type Term =
22        | Binary lhs : i32
23                 rhs : i32
24                 Add | Sub | Mul | Div
25        | t@ i32
26    
27    do
28        let term = Term/Binary/Mul 1 2 |> as_binary |> as_term
29        assert term.is_binary
30        assert term.is_mul
31    
32    do
33        let term = Term/Binary/Add 2 3 |> as<Term>
34        assert term.is_binary
35        assert term.is_add
36    
37        let binary = term.as_binary
38        let add = binary.as_add
39        assert binary.lhs == 2
40        assert add.lhs == 2
41    
42    do
43        let term = 1.as<Term>
44    
45    type Variable = String
46    type Field = String
47    
48    type Invoke @open =
49        variable : Variable
50    
51        | Remove
52    
53    do
54        let variable = Variable "variable"
55        let remove1 = Invoke/Remove variable |> as_invoke
56        let remove2 = Invoke/Remove variable |> as_invoke
57        assert remove1 == remove2
58    
59    type Numeric =
60        inherit Invoke
61    
62        field : Field
63        term : Term
64    
65        Increase | Decrease
66    
67    do
68        let increase = Numeric/Increase variable = Variable "variable"
69                                        field = Field "field"
70                                        term = Term/Binary/Add 1 2 |> as_binary
71    
72        let decrease = Numeric/Decrease variable = Variable "variable"
73                                        field = Field "field"
74                                        term = Term/Binary/Add 1 2 |> as_binary
75    
76        let mut numeric = increase
77        numeric = decrease
78    
79    type Metal @open = enum
80        Iron | Silver | Gold
81    
82    type Metal
83        Nickel | Copper
84    
85    type Platinum = symbol
86        inherit Metal
87    
88    do
89        let mut metal = Metal/Silver
90        metal = Metal/Iron
91        metal = Platinum
92    
93        let name = case metal of
94            Metal/Iron -> "iron"
95            Metal/Silver -> "silver"
96            Platinum -> "platinum"
97    
98        assert name == "platinum"
99    
100   type B =
101       | C n : u32
102       | D a : [u32; 3]
103   
104   type B
105       def f = case self of
106           is B/C -> self
107           else -> fail
108   
109       def f_mut @mut = case self of
110           is B/C -> self
111           else -> fail
112   
113   do
114       let mut b = B/C 1 |> as_b
115       let c = b.f
116       let c_mut = b.f_mut
117       c_mut.n = 3
118       assert c.n == 3
119   
120   type Entry =
121       path : String
122       created : String
123   
124       | File size : u32
125       | Directory entries : Slice<Entry>
126                   | Local
127                   | Remote url : String
128   
129   do
130       let directory = Entry/Directory/Local path = "/home"
131                                             created = "07.05.2024"
132                                             entries = Slice<Entry>.empty
133   
134   type C<T> =
135       x : T
136   
137       | D
138   
139   do
140       let d = C<i32>/D x = 5
141   
142   type Inner =
143       | A i32
144       | B i32
145   
146   type Outer =
147       | i32
148       | t@ Inner
149   
150   do
151       let inner : Inner = Inner/A 7
152       let outer = inner |> as<Outer>
153   
154       if outer ? Inner/A x then
155           assert x == 7
156       else
157           fail
158