aboutsummaryrefslogtreecommitdiffstats
path: root/stdlib/common.milch
blob: f05c6a58a5f09f2ca7f717057c850e2df87f102f (plain)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
(let compose (\[f g]
    (\[x] (f (g x)))))

(let id (\[a] a))

(let mod (\[n k]
    (- n (* k (/ n k)))))

(let not (\[b]
    (match b
        true false
        false true)))

(let is-even (\[n]
    (match (mod n 2)
        0 true
        1 false)))

(let is-odd (compose not is-even))

;; map :: (a -> b) -> [a] -> [b]
(let map (\[f lst]
    (match lst
        []
            []
        otherwise
            (prepend (f (head lst)) (map f (tail lst))))))

; (map (+ 1) [1 2 3])

;; foldr :: (a -> b -> b) -> b -> [a] -> b
(let foldr (\[f accumulator lst]
    (match lst
        []
            accumulator
        otherwise
            (f (head lst) (foldr f accumulator (tail lst))))))

;; filter :: (a -> Bool) -> [a] -> [a]
(let filter (\[pred lst]
    (match lst
        [] []
        otherwise (match (pred (head lst))
            true
                (prepend (head lst) (filter pred (tail lst)))
            false
                (filter pred (tail lst))))))

(let reverse_ (\[v a]
    (let lazy x (head v))
    (let lazy xs (tail v))
    (let lazy xa (prepend x a))
    (match v
        [] a
        _  (reverse_ xs xa))))

(let reverse (\[v]
    (reverse_ v [])))

(let flow (\[fs] (foldr compose id (reverse fs))))
(let pipe (\[x fs] ((flow fs) x)))

(let leq? (\[a b]
    (or?
        (eq? a b)
        (lt? a b))))

(let rt? (compose not leq?))
(let req? (compose not lt?))

(let max2 (\[a b]
    (match (lt? a b)
        true    b
        false   a)))

(let max (\[vals]
    (let lazy v (head vals))
    (let vs (tail vals))

    (match vs
        []          v
        otherwise   (max2 v (max vs)))))

(let split-by' (\[delim acc vals]
    (let lazy v (head vals))
    (let vs (tail vals))

    (match vs
        []          (match v
            delim       [(reverse acc)]
            otherwise   [(prepend v (reverse acc))])
        otherwise   (match v
            delim       (prepend (reverse acc) (split-by' delim [] vs))
            otherwise   (split-by' delim (prepend v acc) vs)))))

; split vector by delimiter
(let split-by (\[delim vals]
    (split-by' delim [] vals)))

(let at (\[n seq]
    (match seq
        []          (fatal! (fmt "at out of bounds, n: {0}" [n]))
        otherwise   (match n
            0           (head seq)
            otherwise   (at (- n 1) (tail seq))))))

(let print-fmt! (\![fstr args]
    (print! (fmt fstr args))))

(let sort-by (\[keyf vals]
    (let sorted (sort-by-first
        (map (\[v]
            [(keyf v) v]) vals)))

    (map (at 1) sorted)))

(let take (\[n xs]
    (match n
        0          []
        otherwise  (prepend (head xs) (take (- n 1) (tail xs))))))

(let drop (\[n xs]
    (match n
        0          xs
        otherwise  (drop (- n 1) (tail xs)))))