1122 | 1122 |
|
1123 | 1123 |
You may want to use helper functions to hide this ugliness.
|
1124 | 1124 |
|
1125 | |
/| struct list {
|
1126 | |
/| value: string;
|
1127 | |
/| next: list|void;
|
1128 | |
/| }
|
1129 | |
/| fun singleton(v: string) {
|
1130 | |
/| make list(value:v, next:null as list|void)
|
1131 | |
/| }
|
1132 | |
/| fun cons(v: string, l: list) {
|
1133 | |
/| make list(value:v, next:l as list|void)
|
1134 | |
/| }
|
1135 | |
/| fun nth(n, l: list) {
|
1136 | |
/| u = l as list|void;
|
1137 | |
/| v = u;
|
1138 | |
/| k = n;
|
1139 | |
/| while k > 1 {
|
1140 | |
/| typecase u is void { break; }
|
1141 | |
/| typecase u is list { v = u.next; }
|
1142 | |
/| u = v;
|
1143 | |
/| k = k - 1;
|
1144 | |
/| }
|
1145 | |
/| return u
|
1146 | |
/| }
|
1147 | |
/| main = fun() {
|
1148 | |
/| l = cons("first", singleton("second"));
|
1149 | |
/| g = nth(2, l);
|
1150 | |
/| typecase g is list { print(g.value); }
|
1151 | |
/| }
|
1152 | |
/= second
|
|
1125 |
| struct list {
|
|
1126 |
| value: string;
|
|
1127 |
| next: list|void;
|
|
1128 |
| }
|
|
1129 |
|
|
|
1130 |
| fun empty() {
|
|
1131 |
| return null as list|void
|
|
1132 |
| }
|
|
1133 |
|
|
|
1134 |
| fun cons(v: string, l: list|void) {
|
|
1135 |
| make list(value:v, next:l) as list|void
|
|
1136 |
| }
|
|
1137 |
|
|
|
1138 |
| fun nth(n, l: list|void) {
|
|
1139 |
| u = l;
|
|
1140 |
| v = u;
|
|
1141 |
| k = n;
|
|
1142 |
| while k > 1 {
|
|
1143 |
| typecase u is void { break; }
|
|
1144 |
| typecase u is list { v = u.next; }
|
|
1145 |
| u = v;
|
|
1146 |
| k = k - 1;
|
|
1147 |
| }
|
|
1148 |
| return u
|
|
1149 |
| }
|
|
1150 |
|
|
|
1151 |
| main = fun() {
|
|
1152 |
| l = cons("first", cons("second", cons("third", empty())));
|
|
1153 |
| h = nth(2, l);
|
|
1154 |
| typecase h is list { print(h.value); }
|
|
1155 |
| }
|
|
1156 |
= second
|
|
1157 |
|
|
1158 |
And in fact, you can restrict the union types to smaller sets to
|
|
1159 |
better indicate the allowable types of the functions. For example,
|
|
1160 |
`cons` always returns a list, so that should be its return type,
|
|
1161 |
not `list|void`. Likewise, `nth` requires a list. In this way we
|
|
1162 |
can implement some of the "Parse, don't Validate" approach.
|
|
1163 |
|
|
1164 |
| struct list {
|
|
1165 |
| value: string;
|
|
1166 |
| next: list|void;
|
|
1167 |
| }
|
|
1168 |
|
|
|
1169 |
| fun cons(v: string, l: list) {
|
|
1170 |
| make list(value:v, next:l as list|void)
|
|
1171 |
| }
|
|
1172 |
|
|
|
1173 |
| fun singleton(v: string) {
|
|
1174 |
| make list(value:v, next:null as list|void)
|
|
1175 |
| }
|
|
1176 |
|
|
|
1177 |
| fun nth(n, l: list) {
|
|
1178 |
| u = l as list|void;
|
|
1179 |
| v = u;
|
|
1180 |
| k = n;
|
|
1181 |
| while k > 1 {
|
|
1182 |
| typecase u is void { break; }
|
|
1183 |
| typecase u is list { v = u.next; }
|
|
1184 |
| u = v;
|
|
1185 |
| k = k - 1;
|
|
1186 |
| }
|
|
1187 |
| return u
|
|
1188 |
| }
|
|
1189 |
|
|
|
1190 |
| main = fun() {
|
|
1191 |
| l = cons("first", cons("second", singleton("third")));
|
|
1192 |
| h = nth(2, l);
|
|
1193 |
| typecase h is list { print(h.value); }
|
|
1194 |
| }
|
|
1195 |
= second
|
1153 | 1196 |
|
1154 | 1197 |
Structs may be empty.
|
1155 | 1198 |
|