~jojo/Carth

ref: 55fb4f948f1f3797078b584dc60b4f7dd68b37ed Carth/std/list.carth -rw-r--r-- 2.1 KiB
55fb4f94JoJo Check `cast` in Infer instead of Gen 4 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
(import std)

(data (List a)
  (LCons (Box [a (List a)]))
  Nil)

(define first
  (fmatch (case (LCons (Box [x _])) (Some x))
          (case Nil None)))
(define first!
  (fmatch (case (LCons (Box [x _])) x)
          (case Nil (panic "first! of empty list"))))

(define rest
  (fmatch (case (LCons (Box [_ xs])) (Some xs))
          (case Nil None)))
(define rest!
  (fmatch (case (LCons (Box [_ xs])) xs)
          (case Nil (panic "rest! of empty list"))))

(define list/uncons
  (fmatch (case (LCons (Box p)) (Some p))
          (case Nil None)))

(define last
  (fmatch (case (LCons (Box [x Nil])) (Some x))
          (case (LCons (Box [_ xs])) (last xs))
          (case Nil None)))
(define last!
  (fmatch (case (LCons (Box [x Nil])) x)
          (case (LCons (Box [_ xs])) (last! xs))
          (case Nil (panic "last! of empty list"))))

(define init
  (fmatch (case Nil None)
          (case xs (Some (init! xs)))))
(define init!
  (fmatch (case (LCons (Box [_ Nil])) Nil)
          (case (LCons (Box [x xs])) (list/cons x (init! xs)))
          (case Nil (panic "init! of empty list"))))

(define list/nil? (fmatch (case Nil True) (case _ False)))

(define (list/reverse xs)
  (define (rev xs a)
    (maybe a (fun ([x xs']) (rev xs' (list/cons x a))) (list/uncons xs)))
  (rev xs Nil))

(define (list/cons x xs)
  (LCons (box [x xs])))

(define (list/iter xs)
  (Iter (fun (Unit)
          (match xs
            (case (LCons (Box [y ys]))
                  (Some [y (list/iter ys)]))
            (case Nil
                  None)))))

(define (list/append xs ys)
  (match xs
    (case (LCons (Box [x xs'])) (list/cons x (list/append xs' ys)))
    (case Nil ys)))

(define list/concat
  (fmatch (case (LCons (Box [xs xss])) (list/append xs (list/concat xss)))
          (case Nil Nil)))

(define (list/map f)
  (fmatch (case (LCons (Box [x xs])) (list/cons (f x) (list/map f xs)))
          (case Nil Nil)))

(define (list/bind f xs)
  (list/concat (list/map f xs)))

(define (list/bindr xs f)
  (list/concat (list/map f xs)))

(define (list/when condition xs)
  (if condition xs Nil))

(define (list/singleton x)
  (list/cons x Nil))