1use std::sync::OnceLock;
2
3use rex_ast::{CompilationUnit, Decl, Symbol};
4use rex_parser::parse;
5
6use crate::{
7 error::TypeError,
8 types::{AdtDecl, BuiltinTypeId, Predicate, Scheme, Type},
9 typesystem::TypeSystem,
10};
11
12fn inject_prelude_classes_and_instances(ts: &mut TypeSystem) -> Result<(), TypeError> {
13 let program = prelude_typeclasses_program()?;
14 for decl in &program.decls {
15 match decl {
16 Decl::Class(class_decl) => ts.register_class_decl(class_decl)?,
17 Decl::Instance(inst_decl) => {
18 ts.register_instance_decl(inst_decl)?;
19 }
20 Decl::Type(..) | Decl::Fn(..) | Decl::DeclareFn(..) | Decl::Import(..) => {}
21 }
22 }
23 Ok(())
24}
25
26pub fn prelude_typeclasses_program() -> Result<&'static CompilationUnit, TypeError> {
27 static PROGRAM: OnceLock<Result<CompilationUnit, String>> = OnceLock::new();
28 let parsed = PROGRAM.get_or_init(|| {
29 let source = include_str!("prelude_typeclasses.rex");
30 match parse(source) {
31 Ok(program) => Ok(program),
32 Err(errs) => {
33 let mut out = String::from("prelude_typeclasses: parse error:");
34 for err in errs {
35 out.push_str(&format!("\n {err}"));
36 }
37 Err(out)
38 }
39 }
40 });
41 match parsed {
42 Ok(program) => Ok(program),
43 Err(msg) => Err(TypeError::Internal(msg.clone())),
44 }
45}
46
47fn inject_prelude_primops(ts: &mut TypeSystem) {
48 let bool_ty = Type::builtin(BuiltinTypeId::Bool);
53 let i32_ty = Type::builtin(BuiltinTypeId::I32);
54 let string_ty = Type::builtin(BuiltinTypeId::String);
55
56 {
63 let eq_types = [
64 BuiltinTypeId::Bool,
65 BuiltinTypeId::U8,
66 BuiltinTypeId::U16,
67 BuiltinTypeId::U32,
68 BuiltinTypeId::U64,
69 BuiltinTypeId::I8,
70 BuiltinTypeId::I16,
71 BuiltinTypeId::I32,
72 BuiltinTypeId::I64,
73 BuiltinTypeId::F32,
74 BuiltinTypeId::F64,
75 BuiltinTypeId::String,
76 BuiltinTypeId::Uuid,
77 BuiltinTypeId::DateTime,
78 ];
79 for builtin in eq_types {
80 let t = Type::builtin(builtin);
81 ts.add_overload(
82 "prim_eq",
83 Scheme::new(
84 vec![],
85 vec![],
86 Type::fun(t.clone(), Type::fun(t.clone(), bool_ty.clone())),
87 ),
88 );
89 ts.add_overload(
90 "prim_ne",
91 Scheme::new(
92 vec![],
93 vec![],
94 Type::fun(t.clone(), Type::fun(t, bool_ty.clone())),
95 ),
96 );
97 }
98 }
99
100 {
104 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
105 let a = Type::var(a_tv.clone());
106 let array_a = Type::app(Type::builtin(BuiltinTypeId::Array), a.clone());
107 ts.add_value(
108 "prim_array_eq",
109 Scheme::new(
110 vec![a_tv.clone()],
111 vec![],
112 Type::fun(array_a.clone(), Type::fun(array_a.clone(), bool_ty.clone())),
113 ),
114 );
115 ts.add_value(
116 "prim_array_ne",
117 Scheme::new(
118 vec![a_tv],
119 vec![],
120 Type::fun(array_a.clone(), Type::fun(array_a, bool_ty.clone())),
121 ),
122 );
123 }
124
125 {
127 let additive = [
128 BuiltinTypeId::String,
129 BuiltinTypeId::U8,
130 BuiltinTypeId::U16,
131 BuiltinTypeId::U32,
132 BuiltinTypeId::U64,
133 BuiltinTypeId::I8,
134 BuiltinTypeId::I16,
135 BuiltinTypeId::I32,
136 BuiltinTypeId::I64,
137 BuiltinTypeId::F32,
138 BuiltinTypeId::F64,
139 ];
140 for builtin in additive {
141 let t = Type::builtin(builtin);
142 ts.add_overload("prim_zero", Scheme::new(vec![], vec![], t.clone()));
143 ts.add_overload(
144 "prim_add",
145 Scheme::new(
146 vec![],
147 vec![],
148 Type::fun(t.clone(), Type::fun(t.clone(), t.clone())),
149 ),
150 );
151 }
152
153 let multiplicative = [
154 BuiltinTypeId::U8,
155 BuiltinTypeId::U16,
156 BuiltinTypeId::U32,
157 BuiltinTypeId::U64,
158 BuiltinTypeId::I8,
159 BuiltinTypeId::I16,
160 BuiltinTypeId::I32,
161 BuiltinTypeId::I64,
162 BuiltinTypeId::F32,
163 BuiltinTypeId::F64,
164 ];
165 for builtin in multiplicative {
166 let t = Type::builtin(builtin);
167 ts.add_overload("prim_one", Scheme::new(vec![], vec![], t.clone()));
168 ts.add_overload(
169 "prim_mul",
170 Scheme::new(
171 vec![],
172 vec![],
173 Type::fun(t.clone(), Type::fun(t.clone(), t.clone())),
174 ),
175 );
176 }
177
178 let subtractive = [
179 BuiltinTypeId::U8,
180 BuiltinTypeId::U16,
181 BuiltinTypeId::U32,
182 BuiltinTypeId::U64,
183 BuiltinTypeId::I8,
184 BuiltinTypeId::I16,
185 BuiltinTypeId::I32,
186 BuiltinTypeId::I64,
187 BuiltinTypeId::F32,
188 BuiltinTypeId::F64,
189 ];
190 for builtin in subtractive {
191 let t = Type::builtin(builtin);
192 ts.add_overload(
193 "prim_sub",
194 Scheme::new(
195 vec![],
196 vec![],
197 Type::fun(t.clone(), Type::fun(t.clone(), t.clone())),
198 ),
199 );
200 }
201
202 let signed = [
203 BuiltinTypeId::I8,
204 BuiltinTypeId::I16,
205 BuiltinTypeId::I32,
206 BuiltinTypeId::I64,
207 BuiltinTypeId::F32,
208 BuiltinTypeId::F64,
209 ];
210 for builtin in signed {
211 let t = Type::builtin(builtin);
212 ts.add_overload(
213 "prim_negate",
214 Scheme::new(vec![], vec![], Type::fun(t.clone(), t.clone())),
215 );
216 }
217
218 let divisive = [
219 BuiltinTypeId::U8,
220 BuiltinTypeId::U16,
221 BuiltinTypeId::U32,
222 BuiltinTypeId::U64,
223 BuiltinTypeId::I8,
224 BuiltinTypeId::I16,
225 BuiltinTypeId::I32,
226 BuiltinTypeId::I64,
227 BuiltinTypeId::F32,
228 BuiltinTypeId::F64,
229 ];
230 for builtin in divisive {
231 let t = Type::builtin(builtin);
232 ts.add_overload(
233 "prim_div",
234 Scheme::new(
235 vec![],
236 vec![],
237 Type::fun(t.clone(), Type::fun(t.clone(), t.clone())),
238 ),
239 );
240 }
241
242 let integral = [
243 BuiltinTypeId::U8,
244 BuiltinTypeId::U16,
245 BuiltinTypeId::U32,
246 BuiltinTypeId::U64,
247 BuiltinTypeId::I8,
248 BuiltinTypeId::I16,
249 BuiltinTypeId::I32,
250 BuiltinTypeId::I64,
251 ];
252 for builtin in integral {
253 let t = Type::builtin(builtin);
254 ts.add_overload(
255 "prim_mod",
256 Scheme::new(
257 vec![],
258 vec![],
259 Type::fun(t.clone(), Type::fun(t.clone(), t.clone())),
260 ),
261 );
262 }
263 }
264
265 {
267 let ord = [
268 BuiltinTypeId::U8,
269 BuiltinTypeId::U16,
270 BuiltinTypeId::U32,
271 BuiltinTypeId::U64,
272 BuiltinTypeId::I8,
273 BuiltinTypeId::I16,
274 BuiltinTypeId::I32,
275 BuiltinTypeId::I64,
276 BuiltinTypeId::F32,
277 BuiltinTypeId::F64,
278 BuiltinTypeId::String,
279 ];
280 for builtin in ord {
281 let t = Type::builtin(builtin);
282 ts.add_overload(
283 "prim_cmp",
284 Scheme::new(
285 vec![],
286 vec![],
287 Type::fun(t.clone(), Type::fun(t.clone(), i32_ty.clone())),
288 ),
289 );
290 for name in ["prim_lt", "prim_le", "prim_gt", "prim_ge"] {
291 ts.add_overload(
292 name,
293 Scheme::new(
294 vec![],
295 vec![],
296 Type::fun(t.clone(), Type::fun(t.clone(), bool_ty.clone())),
297 ),
298 );
299 }
300 }
301 }
302
303 {
305 let show_types = [
306 BuiltinTypeId::Bool,
307 BuiltinTypeId::U8,
308 BuiltinTypeId::U16,
309 BuiltinTypeId::U32,
310 BuiltinTypeId::U64,
311 BuiltinTypeId::I8,
312 BuiltinTypeId::I16,
313 BuiltinTypeId::I32,
314 BuiltinTypeId::I64,
315 BuiltinTypeId::F32,
316 BuiltinTypeId::F64,
317 BuiltinTypeId::String,
318 BuiltinTypeId::Uuid,
319 BuiltinTypeId::DateTime,
320 ];
321 for builtin in show_types {
322 let t = Type::builtin(builtin);
323 ts.add_overload(
324 "prim_show",
325 Scheme::new(vec![], vec![], Type::fun(t, string_ty.clone())),
326 );
327 }
328 }
329
330 {
335 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
336 let a = Type::var(a_tv.clone());
337 ts.add_value(
338 "prim_json_stringify",
339 Scheme::new(vec![a_tv], vec![], Type::fun(a, string_ty.clone())),
340 );
341 }
342
343 {
349 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
350 let a = Type::var(a_tv.clone());
351 let result_con = Type::builtin(BuiltinTypeId::Result);
352 let result_as = Type::app(Type::app(result_con, string_ty.clone()), a);
353 ts.add_value(
354 "prim_json_parse",
355 Scheme::new(vec![a_tv], vec![], Type::fun(string_ty.clone(), result_as)),
356 );
357 }
358
359 {
364 let list_con = Type::builtin(BuiltinTypeId::List);
365 let array_con = Type::builtin(BuiltinTypeId::Array);
366 let option_con = Type::builtin(BuiltinTypeId::Option);
367 let result_con = Type::builtin(BuiltinTypeId::Result);
368
369 let list_of = |t: Type| Type::app(list_con.clone(), t);
370 let array_of = |t: Type| Type::app(array_con.clone(), t);
371 let option_of = |t: Type| Type::app(option_con.clone(), t);
372 let result_of = |ok: Type, err: Type| Type::app(Type::app(result_con.clone(), err), ok);
373
374 {
376 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
377 let b_tv = ts.supply.fresh(Some(Symbol::intern("b")));
378 let a = Type::var(a_tv.clone());
379 let b = Type::var(b_tv.clone());
380 ts.add_overload(
381 "prim_map",
382 Scheme::new(
383 vec![a_tv.clone(), b_tv.clone()],
384 vec![],
385 Type::fun(
386 Type::fun(a.clone(), b.clone()),
387 Type::fun(list_of(a.clone()), list_of(b.clone())),
388 ),
389 ),
390 );
391 ts.add_overload(
392 "prim_map",
393 Scheme::new(
394 vec![a_tv.clone(), b_tv.clone()],
395 vec![],
396 Type::fun(
397 Type::fun(a.clone(), b.clone()),
398 Type::fun(array_of(a.clone()), array_of(b.clone())),
399 ),
400 ),
401 );
402 ts.add_overload(
403 "prim_map",
404 Scheme::new(
405 vec![a_tv.clone(), b_tv.clone()],
406 vec![],
407 Type::fun(
408 Type::fun(a.clone(), b.clone()),
409 Type::fun(option_of(a.clone()), option_of(b.clone())),
410 ),
411 ),
412 );
413 let e_tv = ts.supply.fresh(Some(Symbol::intern("e")));
414 let e = Type::var(e_tv.clone());
415 ts.add_overload(
416 "prim_map",
417 Scheme::new(
418 vec![a_tv, b_tv, e_tv],
419 vec![],
420 Type::fun(
421 Type::fun(a.clone(), b.clone()),
422 Type::fun(result_of(a.clone(), e.clone()), result_of(b.clone(), e)),
423 ),
424 ),
425 );
426 }
427
428 {
430 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
431 let a = Type::var(a_tv.clone());
432 ts.add_value(
433 "prim_array_singleton",
434 Scheme::new(vec![a_tv], vec![], Type::fun(a.clone(), array_of(a))),
435 );
436 }
437
438 {
440 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
441 let b_tv = ts.supply.fresh(Some(Symbol::intern("b")));
442 let a = Type::var(a_tv.clone());
443 let b = Type::var(b_tv.clone());
444 let step_l = Type::fun(b.clone(), Type::fun(a.clone(), b.clone()));
445 let step_r = Type::fun(a.clone(), Type::fun(b.clone(), b.clone()));
446 let mut add_for = |fa: Type| {
447 ts.add_overload(
448 "prim_foldl",
449 Scheme::new(
450 vec![a_tv.clone(), b_tv.clone()],
451 vec![],
452 Type::fun(
453 step_l.clone(),
454 Type::fun(b.clone(), Type::fun(fa.clone(), b.clone())),
455 ),
456 ),
457 );
458 ts.add_overload(
459 "prim_foldr",
460 Scheme::new(
461 vec![a_tv.clone(), b_tv.clone()],
462 vec![],
463 Type::fun(
464 step_r.clone(),
465 Type::fun(b.clone(), Type::fun(fa.clone(), b.clone())),
466 ),
467 ),
468 );
469 ts.add_overload(
470 "prim_fold",
471 Scheme::new(
472 vec![a_tv.clone(), b_tv.clone()],
473 vec![],
474 Type::fun(
475 step_l.clone(),
476 Type::fun(b.clone(), Type::fun(fa, b.clone())),
477 ),
478 ),
479 );
480 };
481
482 add_for(list_of(a.clone()));
483 add_for(array_of(a.clone()));
484 add_for(option_of(a.clone()));
485 }
486
487 {
489 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
490 let b_tv = ts.supply.fresh(Some(Symbol::intern("b")));
491 let a = Type::var(a_tv.clone());
492 let b = Type::var(b_tv.clone());
493 let pred = Type::fun(a.clone(), bool_ty.clone());
494 let mapper = Type::fun(a.clone(), option_of(b.clone()));
495 let mut add_for = |fa: Type, fb: Type| {
496 ts.add_overload(
497 "prim_filter",
498 Scheme::new(
499 vec![a_tv.clone()],
500 vec![],
501 Type::fun(pred.clone(), Type::fun(fa.clone(), fa.clone())),
502 ),
503 );
504 ts.add_overload(
505 "prim_filter_map",
506 Scheme::new(
507 vec![a_tv.clone(), b_tv.clone()],
508 vec![],
509 Type::fun(mapper.clone(), Type::fun(fa, fb)),
510 ),
511 );
512 };
513
514 add_for(list_of(a.clone()), list_of(b.clone()));
515 add_for(array_of(a.clone()), array_of(b.clone()));
516 add_for(option_of(a.clone()), option_of(b.clone()));
517 }
518
519 {
521 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
523 let b_tv = ts.supply.fresh(Some(Symbol::intern("b")));
524 let a = Type::var(a_tv.clone());
525 let b = Type::var(b_tv.clone());
526 let mut add_for = |fa: Type, fb: Type| {
527 ts.add_overload(
528 "prim_flat_map",
529 Scheme::new(
530 vec![a_tv.clone(), b_tv.clone()],
531 vec![],
532 Type::fun(Type::fun(a.clone(), fb.clone()), Type::fun(fa, fb)),
533 ),
534 );
535 };
536
537 add_for(list_of(a.clone()), list_of(b.clone()));
538 add_for(array_of(a.clone()), array_of(b.clone()));
539 add_for(option_of(a.clone()), option_of(b.clone()));
540
541 let e_tv = ts.supply.fresh(Some(Symbol::intern("e")));
543 let e = Type::var(e_tv.clone());
544 let ra = result_of(a.clone(), e.clone());
545 let rb = result_of(b.clone(), e.clone());
546 ts.add_overload(
547 "prim_flat_map",
548 Scheme::new(
549 vec![a_tv, b_tv, e_tv],
550 vec![],
551 Type::fun(Type::fun(a.clone(), rb.clone()), Type::fun(ra, rb)),
552 ),
553 );
554 }
555
556 {
558 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
559 let a = Type::var(a_tv.clone());
560 let mut add_for = |fa: Type| {
561 let fa2 = fa.clone();
562 ts.add_overload(
563 "prim_or_else",
564 Scheme::new(
565 vec![a_tv.clone()],
566 vec![],
567 Type::fun(Type::fun(fa.clone(), fa.clone()), Type::fun(fa2, fa)),
568 ),
569 );
570 };
571
572 add_for(list_of(a.clone()));
573 add_for(array_of(a.clone()));
574 add_for(option_of(a.clone()));
575
576 let e_tv = ts.supply.fresh(Some(Symbol::intern("e")));
577 let e = Type::var(e_tv.clone());
578 let ra = result_of(a.clone(), e);
579 ts.add_overload(
580 "prim_or_else",
581 Scheme::new(
582 vec![a_tv, e_tv],
583 vec![],
584 Type::fun(Type::fun(ra.clone(), ra.clone()), Type::fun(ra.clone(), ra)),
585 ),
586 );
587 }
588
589 {
591 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
592 let a = Type::var(a_tv.clone());
593 let mut add_for = |fa: Type| {
594 let scheme = Scheme::new(
595 vec![a_tv.clone()],
596 vec![],
597 Type::fun(i32_ty.clone(), Type::fun(fa.clone(), fa)),
598 );
599 ts.add_overload("prim_take", scheme.clone());
600 ts.add_overload("prim_skip", scheme);
601 };
602 add_for(list_of(a.clone()));
603 add_for(array_of(a.clone()));
604 }
605
606 {
608 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
609 let b_tv = ts.supply.fresh(Some(Symbol::intern("b")));
610 let a = Type::var(a_tv.clone());
611 let b = Type::var(b_tv.clone());
612 let pair = Type::tuple(vec![a.clone(), b.clone()]);
613 let mut add_for = |fa: Type, fb: Type, fp: Type| {
614 ts.add_overload(
615 "prim_zip",
616 Scheme::new(
617 vec![a_tv.clone(), b_tv.clone()],
618 vec![],
619 Type::fun(fa.clone(), Type::fun(fb.clone(), fp.clone())),
620 ),
621 );
622 ts.add_overload(
623 "prim_unzip",
624 Scheme::new(
625 vec![a_tv.clone(), b_tv.clone()],
626 vec![],
627 Type::fun(fp, Type::tuple(vec![fa, fb])),
628 ),
629 );
630 };
631
632 add_for(
633 list_of(a.clone()),
634 list_of(b.clone()),
635 list_of(pair.clone()),
636 );
637 add_for(array_of(a.clone()), array_of(b.clone()), array_of(pair));
638 }
639
640 {
642 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
643 let a = Type::var(a_tv.clone());
644 let idx = i32_ty.clone();
645 ts.add_overload(
646 "prim_get",
647 Scheme::new(
648 vec![a_tv.clone()],
649 vec![],
650 Type::fun(idx.clone(), Type::fun(list_of(a.clone()), a.clone())),
651 ),
652 );
653 ts.add_overload(
654 "prim_get",
655 Scheme::new(
656 vec![a_tv.clone()],
657 vec![],
658 Type::fun(idx.clone(), Type::fun(array_of(a.clone()), a.clone())),
659 ),
660 );
661 for size in 2..=32 {
662 ts.add_overload(
663 "prim_get",
664 Scheme::new(
665 vec![a_tv.clone()],
666 vec![],
667 Type::fun(
668 idx.clone(),
669 Type::fun(Type::tuple(vec![a.clone(); size]), a.clone()),
670 ),
671 ),
672 );
673 }
674 }
675
676 {
678 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
679 let a = Type::var(a_tv.clone());
680 let list_a = list_of(a.clone());
681 let array_a = array_of(a.clone());
682 ts.add_value(
683 "prim_array_from_list",
684 Scheme::new(
685 vec![a_tv.clone()],
686 vec![],
687 Type::fun(list_a.clone(), array_a.clone()),
688 ),
689 );
690 ts.add_value(
691 "prim_list_from_array",
692 Scheme::new(
693 vec![a_tv.clone()],
694 vec![],
695 Type::fun(array_a.clone(), list_a.clone()),
696 ),
697 );
698 ts.add_value(
699 "to_array",
700 Scheme::new(
701 vec![a_tv.clone()],
702 vec![],
703 Type::fun(list_a.clone(), array_a.clone()),
704 ),
705 );
706 ts.add_value(
707 "to_list",
708 Scheme::new(vec![a_tv], vec![], Type::fun(array_a, list_a)),
709 );
710 }
711
712 {
714 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
715 let b_tv = ts.supply.fresh(Some(Symbol::intern("b")));
716 let a = Type::var(a_tv.clone());
717 let b = Type::var(b_tv.clone());
718 let dict_a = Type::app(Type::builtin(BuiltinTypeId::Dict), a.clone());
719 let dict_b = Type::app(Type::builtin(BuiltinTypeId::Dict), b.clone());
720 ts.add_value(
721 "prim_dict_map",
722 Scheme::new(
723 vec![a_tv, b_tv],
724 vec![],
725 Type::fun(Type::fun(a, b), Type::fun(dict_a, dict_b)),
726 ),
727 );
728 }
729
730 {
732 let a_tv = ts.supply.fresh(Some(Symbol::intern("a")));
733 let b_tv = ts.supply.fresh(Some(Symbol::intern("b")));
734 let e_tv = ts.supply.fresh(Some(Symbol::intern("e")));
735 let a = Type::var(a_tv.clone());
736 let b = Type::var(b_tv.clone());
737 let e = Type::var(e_tv.clone());
738 let dict_a = Type::app(Type::builtin(BuiltinTypeId::Dict), a.clone());
739 let dict_b = Type::app(Type::builtin(BuiltinTypeId::Dict), b.clone());
740 let result_eb = result_of(b.clone(), e.clone());
741 let result_edictb = result_of(dict_b, e);
742 ts.add_value(
743 "prim_dict_traverse_result",
744 Scheme::new(
745 vec![a_tv, b_tv, e_tv],
746 vec![],
747 Type::fun(Type::fun(a, result_eb), Type::fun(dict_a, result_edictb)),
748 ),
749 );
750 }
751
752 for src in [
757 BuiltinTypeId::U8,
758 BuiltinTypeId::U16,
759 BuiltinTypeId::U32,
760 BuiltinTypeId::U64,
761 BuiltinTypeId::I8,
762 BuiltinTypeId::I16,
763 BuiltinTypeId::I32,
764 BuiltinTypeId::I64,
765 BuiltinTypeId::F32,
766 BuiltinTypeId::F64,
767 ] {
768 let t = Type::builtin(src);
769 ts.add_overload(
770 "prim_to_f64",
771 Scheme::new(
772 vec![],
773 vec![],
774 Type::fun(t, Type::builtin(BuiltinTypeId::F64)),
775 ),
776 );
777 }
778
779 for (name, dst) in [
780 ("prim_f64_to_u8", BuiltinTypeId::U8),
781 ("prim_f64_to_u16", BuiltinTypeId::U16),
782 ("prim_f64_to_u32", BuiltinTypeId::U32),
783 ("prim_f64_to_u64", BuiltinTypeId::U64),
784 ("prim_f64_to_i8", BuiltinTypeId::I8),
785 ("prim_f64_to_i16", BuiltinTypeId::I16),
786 ("prim_f64_to_i32", BuiltinTypeId::I32),
787 ("prim_f64_to_i64", BuiltinTypeId::I64),
788 ("prim_f64_to_f32", BuiltinTypeId::F32),
789 ] {
790 let dst_ty = Type::builtin(dst);
791 ts.add_value(
792 name,
793 Scheme::new(
794 vec![],
795 vec![],
796 Type::fun(Type::builtin(BuiltinTypeId::F64), option_of(dst_ty)),
797 ),
798 );
799 }
800
801 ts.add_value(
802 "prim_parse_uuid",
803 Scheme::new(
804 vec![],
805 vec![],
806 Type::fun(
807 Type::builtin(BuiltinTypeId::String),
808 option_of(Type::builtin(BuiltinTypeId::Uuid)),
809 ),
810 ),
811 );
812 ts.add_value(
813 "prim_parse_datetime",
814 Scheme::new(
815 vec![],
816 vec![],
817 Type::fun(
818 Type::builtin(BuiltinTypeId::String),
819 option_of(Type::builtin(BuiltinTypeId::DateTime)),
820 ),
821 ),
822 );
823 }
824}
825
826pub(crate) fn build_prelude(ts: &mut TypeSystem) -> Result<(), TypeError> {
827 let prims = [
829 BuiltinTypeId::U8,
830 BuiltinTypeId::U16,
831 BuiltinTypeId::U32,
832 BuiltinTypeId::U64,
833 BuiltinTypeId::I8,
834 BuiltinTypeId::I16,
835 BuiltinTypeId::I32,
836 BuiltinTypeId::I64,
837 BuiltinTypeId::F32,
838 BuiltinTypeId::F64,
839 BuiltinTypeId::Bool,
840 BuiltinTypeId::String,
841 BuiltinTypeId::Uuid,
842 BuiltinTypeId::DateTime,
843 ];
844 for prim in prims {
845 ts.env.extend(
846 prim.as_symbol(),
847 Scheme::new(vec![], vec![], Type::builtin(prim)),
848 );
849 }
850
851 let result_con = Type::builtin(BuiltinTypeId::Result);
853 let option_con = Type::builtin(BuiltinTypeId::Option);
854
855 {
857 let list_name = Symbol::intern("List");
858 let a_name = Symbol::intern("a");
859 let list_params = vec![a_name.clone()];
860 let mut list_adt = AdtDecl::new(&list_name, &list_params, &mut ts.supply);
861 let a = list_adt.param_type(&a_name).ok_or_else(|| {
862 TypeError::Internal("prelude: List is missing type parameter `a`".into())
863 })?;
864 let list_a = list_adt.result_type();
865 list_adt.add_variant(Symbol::intern("Empty"), vec![]);
866 list_adt.add_variant(Symbol::intern("Cons"), vec![a.clone(), list_a.clone()]);
867 ts.register_adt(&list_adt);
868 }
869 {
870 let option_name = Symbol::intern("Option");
871 let t_name = Symbol::intern("t");
872 let option_params = vec![t_name.clone()];
873 let mut option_adt = AdtDecl::new(&option_name, &option_params, &mut ts.supply);
874 let t = option_adt.param_type(&t_name).ok_or_else(|| {
875 TypeError::Internal("prelude: Option is missing type parameter `t`".into())
876 })?;
877 option_adt.add_variant(Symbol::intern("Some"), vec![t]);
878 option_adt.add_variant(Symbol::intern("None"), vec![]);
879 ts.register_adt(&option_adt);
880 }
881 {
882 let result_name = Symbol::intern("Result");
883 let e_name = Symbol::intern("e");
884 let t_name = Symbol::intern("t");
885 let result_params = vec![e_name.clone(), t_name.clone()];
886 let mut result_adt = AdtDecl::new(&result_name, &result_params, &mut ts.supply);
887 let e = result_adt.param_type(&e_name).ok_or_else(|| {
888 TypeError::Internal("prelude: Result is missing type parameter `e`".into())
889 })?;
890 let t = result_adt.param_type(&t_name).ok_or_else(|| {
891 TypeError::Internal("prelude: Result is missing type parameter `t`".into())
892 })?;
893 result_adt.add_variant(Symbol::intern("Err"), vec![e]);
894 result_adt.add_variant(Symbol::intern("Ok"), vec![t]);
895 ts.register_adt(&result_adt);
896 }
897
898 inject_prelude_primops(ts);
899 inject_prelude_classes_and_instances(ts)?;
900
901 let fresh_tv = |ts: &mut TypeSystem, name: &str| ts.supply.fresh(Some(Symbol::intern(name)));
903 let option_of = |t: Type| Type::app(option_con.clone(), t);
904 let result_of = |t: Type, e: Type| Type::app(Type::app(result_con.clone(), e), t);
905
906 let bool_ty = Type::builtin(BuiltinTypeId::Bool);
910 ts.add_value(
911 "&&",
912 Scheme::new(
913 vec![],
914 vec![],
915 Type::fun(bool_ty.clone(), Type::fun(bool_ty.clone(), bool_ty.clone())),
916 ),
917 );
918 ts.add_value(
919 "||",
920 Scheme::new(
921 vec![],
922 vec![],
923 Type::fun(bool_ty.clone(), Type::fun(bool_ty.clone(), bool_ty.clone())),
924 ),
925 );
926
927 {
929 let f_tv = fresh_tv(ts, "f");
930 let a_tv = fresh_tv(ts, "a");
931 let f = Type::var(f_tv.clone());
932 let a = Type::var(a_tv.clone());
933 let fa = Type::app(f.clone(), a.clone());
934
935 ts.add_value(
936 "sum",
937 Scheme::new(
938 vec![f_tv.clone(), a_tv.clone()],
939 vec![
940 Predicate::new("Foldable", f.clone()),
941 Predicate::new("AdditiveMonoid", a.clone()),
942 ],
943 Type::fun(fa.clone(), a.clone()),
944 ),
945 );
946 ts.add_value(
947 "mean",
948 Scheme::new(
949 vec![f_tv.clone(), a_tv.clone()],
950 vec![
951 Predicate::new("Foldable", f.clone()),
952 Predicate::new("Field", a.clone()),
953 ],
954 Type::fun(fa.clone(), a.clone()),
955 ),
956 );
957 ts.add_value(
958 "count",
959 Scheme::new(
960 vec![f_tv.clone(), a_tv.clone()],
961 vec![Predicate::new("Foldable", f.clone())],
962 Type::fun(fa.clone(), Type::builtin(BuiltinTypeId::I32)),
963 ),
964 );
965 ts.add_value(
966 "min",
967 Scheme::new(
968 vec![f_tv.clone(), a_tv.clone()],
969 vec![
970 Predicate::new("Foldable", f.clone()),
971 Predicate::new("Ord", a.clone()),
972 ],
973 Type::fun(fa.clone(), a.clone()),
974 ),
975 );
976 ts.add_value(
977 "max",
978 Scheme::new(
979 vec![f_tv, a_tv],
980 vec![
981 Predicate::new("Foldable", f.clone()),
982 Predicate::new("Ord", a.clone()),
983 ],
984 Type::fun(fa.clone(), a.clone()),
985 ),
986 );
987 }
988
989 {
991 let a_tv = fresh_tv(ts, "a");
992 let a = Type::var(a_tv.clone());
993 let opt_a = option_of(a.clone());
994 ts.add_value(
995 "unwrap",
996 Scheme::new(
997 vec![a_tv.clone()],
998 vec![],
999 Type::fun(opt_a.clone(), a.clone()),
1000 ),
1001 );
1002 ts.add_value(
1003 "is_some",
1004 Scheme::new(
1005 vec![a_tv.clone()],
1006 vec![],
1007 Type::fun(opt_a.clone(), bool_ty.clone()),
1008 ),
1009 );
1010 ts.add_value(
1011 "is_none",
1012 Scheme::new(
1013 vec![a_tv.clone()],
1014 vec![],
1015 Type::fun(opt_a.clone(), bool_ty.clone()),
1016 ),
1017 );
1018 }
1019
1020 {
1022 let t_tv = fresh_tv(ts, "t");
1023 let e_tv = fresh_tv(ts, "e");
1024 let t = Type::var(t_tv.clone());
1025 let e = Type::var(e_tv.clone());
1026 let res_te = result_of(t.clone(), e.clone());
1027 ts.add_overload(
1028 "unwrap",
1029 Scheme::new(
1030 vec![t_tv.clone(), e_tv.clone()],
1031 vec![],
1032 Type::fun(res_te.clone(), t.clone()),
1033 ),
1034 );
1035 ts.add_value(
1036 "is_ok",
1037 Scheme::new(
1038 vec![t_tv.clone(), e_tv.clone()],
1039 vec![],
1040 Type::fun(res_te.clone(), bool_ty.clone()),
1041 ),
1042 );
1043 ts.add_value(
1044 "is_err",
1045 Scheme::new(
1046 vec![t_tv.clone(), e_tv.clone()],
1047 vec![],
1048 Type::fun(res_te.clone(), bool_ty.clone()),
1049 ),
1050 );
1051 }
1052
1053 Ok(())
1054}