@explorable-viz/fluid 0.10.5 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fluid/fluid/lib/matrix.fld +14 -18
 - package/dist/fluid/fluid/lib/prelude.fld +79 -8
 - package/dist/fluid/fluid/lib/stats.fld +25 -28
 - package/dist/fluid/shared/fluid.mjs +3198 -2256
 - package/dist/fluid/shared/load-figure.js +11050 -4052
 - package/dist/fluid/shared/webtest-lib.js +29073 -29877
 - package/package.json +8 -5
 - package/website/article/convolution/index.html +5 -5
 - package/website/article/dataset/annual-temp-anomaly.json +413 -0
 - package/website/article/dataset/ccra3-risks.json +2015 -0
 - package/website/article/energy-scatter/index.html +47 -0
 - package/website/article/fluid/bar-chart-line-chart.fld +5 -5
 - package/website/article/fluid/convolution/emboss.fld +5 -1
 - package/website/article/fluid/dataset/scigen/_1805_02474v1_10.fld +1 -1
 - package/website/article/fluid/energyscatter.fld +27 -0
 - package/website/article/fluid/methane.fld +23 -1
 - package/website/article/fluid/methane_data.fld +1 -0
 - package/website/article/fluid/moving-average.fld +1 -1
 - package/website/article/fluid/nonRenewables.fld +2 -2
 - package/website/article/fluid/renewables.fld +1 -1
 - package/website/article/methane/index.html +46 -0
 - package/website/article/moving-average/index.html +2 -2
 - package/website/article/non-renewables/index.html +2 -2
 - package/website/article/renewables-linked/index.html +2 -2
 - package/website/article/scigen-1805.02474v1-10/index.html +2 -2
 - package/website/article/test.mjs +3 -1
 - /package/website/article/{fluid/dataset/scigen → dataset/SciGen}/1805.02474v1-10.json +0 -0
 - /package/website/article/{fluid/dataset → dataset}/methane-emissions.json +0 -0
 - /package/website/article/{fluid/dataset → dataset}/non-renewables.json +0 -0
 - /package/website/article/{fluid/dataset → dataset}/renewable-new.json +0 -0
 - /package/website/article/{fluid/dataset → dataset}/renewable.json +0 -0
 
| 
         @@ -1,44 +1,40 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            def zero(m, n, image):
         
     | 
| 
       2 
     | 
    
         
            -
              def (m_max, n_max): dims(image) 
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 2 
     | 
    
         
            +
              def (m_max, n_max): dims(image)
         
     | 
| 
       4 
3 
     | 
    
         
             
              if m >= 1 |and| m <= m_max |and| n >= 1 |and| n <= n_max: image ! (m, n)
         
     | 
| 
       5 
     | 
    
         
            -
              else: 0 
     | 
| 
      
 4 
     | 
    
         
            +
              else: 0
         
     | 
| 
       6 
5 
     | 
    
         | 
| 
       7 
6 
     | 
    
         
             
            def wrap(m, n, image):
         
     | 
| 
       8 
     | 
    
         
            -
              def (m_max, n_max): dims(image) 
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
              image ! (((m - 1) |mod| m_max) + 1, ((n - 1) |mod| n_max) + 1);
         
     | 
| 
      
 7 
     | 
    
         
            +
              def (m_max, n_max): dims(image)
         
     | 
| 
      
 8 
     | 
    
         
            +
              image ! (((m - 1) |mod| m_max) + 1, ((n - 1) |mod| n_max) + 1)
         
     | 
| 
       11 
9 
     | 
    
         | 
| 
       12 
10 
     | 
    
         
             
            def extend(m, n, image):
         
     | 
| 
       13 
11 
     | 
    
         
             
              def (m_max, n_max): dims(image)
         
     | 
| 
       14 
12 
     | 
    
         
             
              def m':
         
     | 
| 
       15 
13 
     | 
    
         
             
                min(max(m, 1), m_max)
         
     | 
| 
       16 
14 
     | 
    
         
             
              def n':
         
     | 
| 
       17 
     | 
    
         
            -
                min(max(n, 1), n_max) 
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
              image ! (m', n');
         
     | 
| 
      
 15 
     | 
    
         
            +
                min(max(n, 1), n_max)
         
     | 
| 
      
 16 
     | 
    
         
            +
              image ! (m', n')
         
     | 
| 
       20 
17 
     | 
    
         | 
| 
       21 
18 
     | 
    
         
             
            def matrixSum(matr):
         
     | 
| 
       22 
     | 
    
         
            -
              def (m, n): dims(matr) 
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
              foldl((+), 0, [matr ! (i, j) for (i, j) in range((1, 1), (m, n))]);
         
     | 
| 
      
 19 
     | 
    
         
            +
              def (m, n): dims(matr)
         
     | 
| 
      
 20 
     | 
    
         
            +
              foldl((+), 0, [matr ! (i, j) for (i, j) in range((1, 1), (m, n))])
         
     | 
| 
       25 
21 
     | 
    
         | 
| 
       26 
22 
     | 
    
         
             
            def convolve(image, kernel, lookup):
         
     | 
| 
       27 
23 
     | 
    
         
             
              def ((m, n), (i, j)):
         
     | 
| 
       28 
24 
     | 
    
         
             
                (dims(image), dims(kernel))
         
     | 
| 
       29 
25 
     | 
    
         
             
              def (half_i, half_j):
         
     | 
| 
       30 
26 
     | 
    
         
             
                (i |quot| 2, j |quot| 2)
         
     | 
| 
       31 
     | 
    
         
            -
              def area: i * j 
     | 
| 
      
 27 
     | 
    
         
            +
              def area: i * j
         
     | 
| 
       32 
28 
     | 
    
         
             
              def interMatrix(m', n'):
         
     | 
| 
       33 
     | 
    
         
            -
                 
     | 
| 
       34 
     | 
    
         
            -
                [| @doc("""Multiply these two elements""") lookup(((m' + i') - 1) - half_i, ((n' + j') - 1) - half_j, image) * kernel ! (i', j') for (i', j') in (i, j) |];
         
     | 
| 
      
 29 
     | 
    
         
            +
                [| lookup(((m' + i') - 1) - half_i, ((n' + j') - 1) - half_j, image) * kernel ! (i', j') for (i', j') in (i, j) |]
         
     | 
| 
       35 
30 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
              [| matrixSum(interMatrix(m', n')) |quot| area for (m', n') in (m, n) |] 
     | 
| 
      
 31 
     | 
    
         
            +
              [| matrixSum(interMatrix(m', n')) |quot| area for (m', n') in (m, n) |]
         
     | 
| 
       37 
32 
     | 
    
         | 
| 
       38 
33 
     | 
    
         
             
            def matMul(a, b):
         
     | 
| 
       39 
     | 
    
         
            -
              def ((m, n), (i, j)): (dims(a), dims(b)) 
     | 
| 
      
 34 
     | 
    
         
            +
              def ((m, n), (i, j)): (dims(a), dims(b))
         
     | 
| 
       40 
35 
     | 
    
         | 
| 
       41 
36 
     | 
    
         
             
              if not(n == i):
         
     | 
| 
       42 
37 
     | 
    
         
             
                error("Dimensions don't line up")
         
     | 
| 
       43 
38 
     | 
    
         
             
              else:
         
     | 
| 
       44 
     | 
    
         
            -
                @doc("""Intermediate matrix""") 
     | 
| 
      
 39 
     | 
    
         
            +
                @doc("""Intermediate matrix""")
         
     | 
| 
      
 40 
     | 
    
         
            +
                [| sum([a!(i_, k) * b!(k, j_) for k in enumFromTo(1, n)]) for (i_, j_) in (m, j) |]
         
     | 
| 
         @@ -1,74 +1,103 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # "Num" throughout means (Int + Float).
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Bool -> Bool
         
     | 
| 
       1 
4 
     | 
    
         
             
            def and(False, y): False
         
     | 
| 
       2 
5 
     | 
    
         
             
            def and(True, y): y
         
     | 
| 
       3 
6 
     | 
    
         | 
| 
      
 7 
     | 
    
         
            +
            # Bool -> Bool
         
     | 
| 
       4 
8 
     | 
    
         
             
            def or(True, y): True
         
     | 
| 
       5 
9 
     | 
    
         
             
            def or(False, y): y
         
     | 
| 
       6 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
            # Bool -> Bool
         
     | 
| 
       7 
12 
     | 
    
         
             
            def not(True): False
         
     | 
| 
       8 
13 
     | 
    
         
             
            def not(False): True
         
     | 
| 
       9 
14 
     | 
    
         | 
| 
      
 15 
     | 
    
         
            +
            # Int -> Int -> Ordering
         
     | 
| 
       10 
16 
     | 
    
         
             
            def compare(x, y):
         
     | 
| 
       11 
17 
     | 
    
         
             
              if x > y: GT
         
     | 
| 
       12 
18 
     | 
    
         
             
              else:
         
     | 
| 
       13 
19 
     | 
    
         
             
                if x < y: LT
         
     | 
| 
       14 
20 
     | 
    
         
             
                else: EQ
         
     | 
| 
       15 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
            # Num -> Num
         
     | 
| 
       16 
23 
     | 
    
         
             
            def negate: (-)(0)
         
     | 
| 
       17 
24 
     | 
    
         | 
| 
      
 25 
     | 
    
         
            +
            # Log of x in base y.
         
     | 
| 
      
 26 
     | 
    
         
            +
            # Float -> Float -> Float
         
     | 
| 
       18 
27 
     | 
    
         
             
            def logBase(x, y): log(y) / log(x)
         
     | 
| 
       19 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
            # Float -> Float -> Float
         
     | 
| 
       20 
30 
     | 
    
         
             
            def ceilingToNearest(n, m): ceiling(n / m) * m
         
     | 
| 
       21 
31 
     | 
    
         | 
| 
      
 32 
     | 
    
         
            +
            # (b -> c) -> (a -> b) -> a -> c
         
     | 
| 
      
 33 
     | 
    
         
            +
            # Want infix <<<
         
     | 
| 
       22 
34 
     | 
    
         
             
            def compose(f, g, x): f(g(x))
         
     | 
| 
       23 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
            # ((a, b) -> c) -> a -> b -> c
         
     | 
| 
       24 
37 
     | 
    
         
             
            def curry(f, x, y): f((x, y))
         
     | 
| 
       25 
38 
     | 
    
         | 
| 
      
 39 
     | 
    
         
            +
            # (a -> b -> c) -> (a, b) -> c
         
     | 
| 
       26 
40 
     | 
    
         
             
            def uncurry(f, (x, y)): f(x, y)
         
     | 
| 
       27 
41 
     | 
    
         | 
| 
      
 42 
     | 
    
         
            +
            # a -> b -> a
         
     | 
| 
       28 
43 
     | 
    
         
             
            def const(x, _): x
         
     | 
| 
       29 
44 
     | 
    
         | 
| 
      
 45 
     | 
    
         
            +
            # (a -> b) -> (a, c) -> (b, c)
         
     | 
| 
       30 
46 
     | 
    
         
             
            def first(f, (a, c)): (f(a), c)
         
     | 
| 
       31 
47 
     | 
    
         | 
| 
      
 48 
     | 
    
         
            +
            # (a, b) -> b
         
     | 
| 
       32 
49 
     | 
    
         
             
            def snd((_, y)): y
         
     | 
| 
       33 
50 
     | 
    
         | 
| 
      
 51 
     | 
    
         
            +
            # (a -> b) -> (c, a) -> (c, b)
         
     | 
| 
       34 
52 
     | 
    
         
             
            def second(f, (c, a)): (c, f(a))
         
     | 
| 
       35 
53 
     | 
    
         | 
| 
      
 54 
     | 
    
         
            +
            # (a -> b -> c) -> b -> a -> c
         
     | 
| 
       36 
55 
     | 
    
         
             
            def flip(f, x, y): f(y, x)
         
     | 
| 
       37 
56 
     | 
    
         | 
| 
      
 57 
     | 
    
         
            +
            # (a, b) -> a
         
     | 
| 
       38 
58 
     | 
    
         
             
            def fst((x, _)): x
         
     | 
| 
       39 
59 
     | 
    
         | 
| 
      
 60 
     | 
    
         
            +
            # a -> a
         
     | 
| 
       40 
61 
     | 
    
         
             
            def id(x): x
         
     | 
| 
       41 
62 
     | 
    
         | 
| 
      
 63 
     | 
    
         
            +
            # (a -> b) -> (a -> c) -> a -> (b, c)
         
     | 
| 
      
 64 
     | 
    
         
            +
            # Want infix &&&
         
     | 
| 
       42 
65 
     | 
    
         
             
            def prod(f, g, x): (f(x), g(x))
         
     | 
| 
       43 
66 
     | 
    
         | 
| 
      
 67 
     | 
    
         
            +
            # (a, b) -> (b, a)
         
     | 
| 
       44 
68 
     | 
    
         
             
            def swap((a, b)): (b, a)
         
     | 
| 
       45 
69 
     | 
    
         | 
| 
      
 70 
     | 
    
         
            +
            # List a -> a
         
     | 
| 
       46 
71 
     | 
    
         
             
            def head([]):
         
     | 
| 
       47 
72 
     | 
    
         
             
              error("Can't take head of empty list")
         
     | 
| 
       48 
73 
     | 
    
         
             
            def head(x :| _): x
         
     | 
| 
       49 
74 
     | 
    
         | 
| 
      
 75 
     | 
    
         
            +
            # List a -> List a
         
     | 
| 
       50 
76 
     | 
    
         
             
            def tail([]):
         
     | 
| 
       51 
77 
     | 
    
         
             
              error("Can't take tail of empty list")
         
     | 
| 
       52 
78 
     | 
    
         
             
            def tail(_ :| xs): xs
         
     | 
| 
       53 
79 
     | 
    
         | 
| 
      
 80 
     | 
    
         
            +
            # Eq a => a -> List a -> Bool
         
     | 
| 
       54 
81 
     | 
    
         
             
            def elem(x, []): False
         
     | 
| 
       55 
82 
     | 
    
         
             
            def elem(x, y :| xs):
         
     | 
| 
       56 
83 
     | 
    
         
             
              x == y |or| elem(x, xs)
         
     | 
| 
       57 
84 
     | 
    
         | 
| 
      
 85 
     | 
    
         
            +
            # (a -> Bool) -> List a -> Option a
         
     | 
| 
       58 
86 
     | 
    
         
             
            def find(p, []): error("not found")
         
     | 
| 
       59 
87 
     | 
    
         
             
            def find(p, x :| xs):
         
     | 
| 
       60 
88 
     | 
    
         
             
              if p(x): Some(x)
         
     | 
| 
       61 
89 
     | 
    
         
             
              else: find(p, xs)
         
     | 
| 
       62 
90 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
      
 91 
     | 
    
         
            +
            # String -> String -> List Dict -> Option Dict
         
     | 
| 
      
 92 
     | 
    
         
            +
            def findWithKey(fname, fval, d):
         
     | 
| 
      
 93 
     | 
    
         
            +
              find((lambda y: y[fname] == fval), d)
         
     | 
| 
       65 
94 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                case Some(x): x
         
     | 
| 
      
 95 
     | 
    
         
            +
            # Option a -> a
         
     | 
| 
      
 96 
     | 
    
         
            +
            def fromSome(None):
         
     | 
| 
      
 97 
     | 
    
         
            +
              error("Expected Some!")
         
     | 
| 
      
 98 
     | 
    
         
            +
            def fromSome(Some(x)): x
         
     | 
| 
       71 
99 
     | 
    
         | 
| 
      
 100 
     | 
    
         
            +
            # (a -> Bool) -> List a -> List a
         
     | 
| 
       72 
101 
     | 
    
         
             
            def filter(p, []): []
         
     | 
| 
       73 
102 
     | 
    
         
             
            def filter(p, x :| xs):
         
     | 
| 
       74 
103 
     | 
    
         
             
              def ys: filter(p, xs)
         
     | 
| 
         @@ -76,6 +105,7 @@ def filter(p, x :| xs): 
     | 
|
| 
       76 
105 
     | 
    
         
             
              if p(x): x :| ys
         
     | 
| 
       77 
106 
     | 
    
         
             
              else: ys
         
     | 
| 
       78 
107 
     | 
    
         | 
| 
      
 108 
     | 
    
         
            +
            # (a -> Option b) -> List a -> List b
         
     | 
| 
       79 
109 
     | 
    
         
             
            def filterMap(p, []): []
         
     | 
| 
       80 
110 
     | 
    
         
             
            def filterMap(p, x :| xs):
         
     | 
| 
       81 
111 
     | 
    
         
             
              match p(x):
         
     | 
| 
         @@ -83,20 +113,25 @@ def filterMap(p, x :| xs): 
     | 
|
| 
       83 
113 
     | 
    
         
             
                case Some(y):
         
     | 
| 
       84 
114 
     | 
    
         
             
                  y :| filterMap(f, xs)
         
     | 
| 
       85 
115 
     | 
    
         | 
| 
      
 116 
     | 
    
         
            +
            # (a -> b -> a) -> a -> List b -> a
         
     | 
| 
       86 
117 
     | 
    
         
             
            def foldl(op, z, []): z
         
     | 
| 
       87 
118 
     | 
    
         
             
            def foldl(op, z, x :| xs):
         
     | 
| 
       88 
119 
     | 
    
         
             
              foldl(op, op(z, x), xs)
         
     | 
| 
       89 
120 
     | 
    
         | 
| 
      
 121 
     | 
    
         
            +
            # (a -> b -> a) -> List b -> a
         
     | 
| 
       90 
122 
     | 
    
         
             
            def foldl1(op, x :| xs): foldl(op, x, xs)
         
     | 
| 
       91 
123 
     | 
    
         | 
| 
      
 124 
     | 
    
         
            +
            # (a -> b -> b) -> b -> List a -> b
         
     | 
| 
       92 
125 
     | 
    
         
             
            def foldr(op, z, []): z
         
     | 
| 
       93 
126 
     | 
    
         
             
            def foldr(op, z, x :| xs):
         
     | 
| 
       94 
127 
     | 
    
         
             
              op(x, foldr(op, z, xs))
         
     | 
| 
       95 
128 
     | 
    
         | 
| 
      
 129 
     | 
    
         
            +
            # (a -> b -> b) -> List a -> b
         
     | 
| 
       96 
130 
     | 
    
         
             
            def foldr1(op, [x]): x
         
     | 
| 
       97 
131 
     | 
    
         
             
            def foldr1(op, x :| y :| xs):
         
     | 
| 
       98 
132 
     | 
    
         
             
              op(x, foldr1(op, y :| xs))
         
     | 
| 
       99 
133 
     | 
    
         | 
| 
      
 134 
     | 
    
         
            +
            # (a -> b -> a) -> a -> List b -> List a
         
     | 
| 
       100 
135 
     | 
    
         
             
            def scanl1(op, z, xs):
         
     | 
| 
       101 
136 
     | 
    
         
             
              def go(x, continue, acc):
         
     | 
| 
       102 
137 
     | 
    
         
             
                def next: op(acc, x)
         
     | 
| 
         @@ -105,48 +140,63 @@ def scanl1(op, z, xs): 
     | 
|
| 
       105 
140 
     | 
    
         | 
| 
       106 
141 
     | 
    
         
             
              foldr(go, const([]), xs, z)
         
     | 
| 
       107 
142 
     | 
    
         | 
| 
      
 143 
     | 
    
         
            +
            # (a -> b -> a) -> a -> List b -> List a
         
     | 
| 
       108 
144 
     | 
    
         
             
            def scanl(op, z, xs):
         
     | 
| 
       109 
145 
     | 
    
         
             
              z :| scanl1(op, z, xs)
         
     | 
| 
       110 
146 
     | 
    
         | 
| 
      
 147 
     | 
    
         
            +
            # (a -> b) -> List a -> List b
         
     | 
| 
       111 
148 
     | 
    
         
             
            def map(f, []): []
         
     | 
| 
       112 
149 
     | 
    
         
             
            def map(f, x :| xs): f(x) :| map(f, xs)
         
     | 
| 
       113 
150 
     | 
    
         | 
| 
      
 151 
     | 
    
         
            +
            # (List a, List a) -> List a
         
     | 
| 
       114 
152 
     | 
    
         
             
            def append(([], ys)): ys
         
     | 
| 
       115 
153 
     | 
    
         
             
            def append((x :| xs, ys)):
         
     | 
| 
       116 
154 
     | 
    
         
             
              x :| append((xs, ys))
         
     | 
| 
       117 
155 
     | 
    
         | 
| 
      
 156 
     | 
    
         
            +
            # List a -> List -> List a
         
     | 
| 
      
 157 
     | 
    
         
            +
            # Want infix ++
         
     | 
| 
       118 
158 
     | 
    
         
             
            def concat2([], ys): ys
         
     | 
| 
       119 
159 
     | 
    
         
             
            def concat2(x :| xs, ys):
         
     | 
| 
       120 
160 
     | 
    
         
             
              x :| concat2(xs, ys)
         
     | 
| 
       121 
161 
     | 
    
         | 
| 
      
 162 
     | 
    
         
            +
            # List (List a) -> List a
         
     | 
| 
       122 
163 
     | 
    
         
             
            def concat: foldl(concat2, [])
         
     | 
| 
       123 
164 
     | 
    
         | 
| 
      
 165 
     | 
    
         
            +
            # (a -> List b) -> List a -> List b
         
     | 
| 
       124 
166 
     | 
    
         
             
            def concatMap(f, xs): concat(map(f, xs))
         
     | 
| 
       125 
167 
     | 
    
         | 
| 
      
 168 
     | 
    
         
            +
            # List a -> a -> List a
         
     | 
| 
       126 
169 
     | 
    
         
             
            def intersperse([], _): []
         
     | 
| 
       127 
170 
     | 
    
         
             
            def intersperse([x], _): [x]
         
     | 
| 
       128 
171 
     | 
    
         
             
            def intersperse(x :| y :| ys, sep):
         
     | 
| 
       129 
172 
     | 
    
         
             
              x :| sep :| intersperse(y :| ys, sep)
         
     | 
| 
       130 
173 
     | 
    
         | 
| 
      
 174 
     | 
    
         
            +
            # Int -> (a -> a) -> a -> List a
         
     | 
| 
       131 
175 
     | 
    
         
             
            def iterate(n, f, z):
         
     | 
| 
       132 
176 
     | 
    
         
             
              if n == 0: []
         
     | 
| 
       133 
177 
     | 
    
         
             
              else:
         
     | 
| 
       134 
178 
     | 
    
         
             
                z :| map(f, iterate(n - 1, f, z))
         
     | 
| 
       135 
179 
     | 
    
         | 
| 
      
 180 
     | 
    
         
            +
            # List Int -> Int
         
     | 
| 
       136 
181 
     | 
    
         
             
            def sum: foldr((+), 0)
         
     | 
| 
       137 
182 
     | 
    
         | 
| 
      
 183 
     | 
    
         
            +
            # List a -> a
         
     | 
| 
       138 
184 
     | 
    
         
             
            def last([x]): x
         
     | 
| 
       139 
185 
     | 
    
         
             
            def last(x :| y :| ys): last(y :| ys)
         
     | 
| 
       140 
186 
     | 
    
         | 
| 
      
 187 
     | 
    
         
            +
            # List a -> Int
         
     | 
| 
       141 
188 
     | 
    
         
             
            def length([]): 0
         
     | 
| 
       142 
189 
     | 
    
         
             
            def length(_ :| xs): 1 + length(xs)
         
     | 
| 
       143 
190 
     | 
    
         | 
| 
      
 191 
     | 
    
         
            +
            # List a -> List a
         
     | 
| 
       144 
192 
     | 
    
         
             
            def reverse([]): []
         
     | 
| 
       145 
193 
     | 
    
         
             
            def reverse(x :| xs):
         
     | 
| 
       146 
194 
     | 
    
         
             
              append((reverse(xs), [x]))
         
     | 
| 
       147 
195 
     | 
    
         | 
| 
      
 196 
     | 
    
         
            +
            # Int -> a -> List a
         
     | 
| 
       148 
197 
     | 
    
         
             
            def repeat: flip(iterate, id)
         
     | 
| 
       149 
198 
     | 
    
         | 
| 
      
 199 
     | 
    
         
            +
            # Int -> List a -> List a
         
     | 
| 
       150 
200 
     | 
    
         
             
            def take(n, xs):
         
     | 
| 
       151 
201 
     | 
    
         
             
              if n <= 0: []
         
     | 
| 
       152 
202 
     | 
    
         
             
              else:
         
     | 
| 
         @@ -155,6 +205,7 @@ def take(n, xs): 
     | 
|
| 
       155 
205 
     | 
    
         
             
                  case x :| xs:
         
     | 
| 
       156 
206 
     | 
    
         
             
                    x :| take(n - 1, xs)
         
     | 
| 
       157 
207 
     | 
    
         | 
| 
      
 208 
     | 
    
         
            +
            # Int -> List a -> List a
         
     | 
| 
       158 
209 
     | 
    
         
             
            def drop(n, xs):
         
     | 
| 
       159 
210 
     | 
    
         
             
              if n <= 0: xs
         
     | 
| 
       160 
211 
     | 
    
         
             
              else:
         
     | 
| 
         @@ -162,58 +213,76 @@ def drop(n, xs): 
     | 
|
| 
       162 
213 
     | 
    
         
             
                  case []: []
         
     | 
| 
       163 
214 
     | 
    
         
             
                  case _ :| xs: drop(n - 1, xs)
         
     | 
| 
       164 
215 
     | 
    
         | 
| 
      
 216 
     | 
    
         
            +
            # Int -> List a -> List a
         
     | 
| 
       165 
217 
     | 
    
         
             
            def lastN(n, xs):
         
     | 
| 
       166 
218 
     | 
    
         
             
              foldl(compose(const, drop(1)), xs, drop(n, xs))
         
     | 
| 
       167 
219 
     | 
    
         | 
| 
      
 220 
     | 
    
         
            +
            # Expects non-negative integer as first argument and non-empty list as second argument.
         
     | 
| 
      
 221 
     | 
    
         
            +
            # Int -> List a -> a
         
     | 
| 
       168 
222 
     | 
    
         
             
            def nth(n, x :| xs):
         
     | 
| 
       169 
223 
     | 
    
         
             
              if n == 0: x
         
     | 
| 
       170 
224 
     | 
    
         
             
              else: nth(n - 1, xs)
         
     | 
| 
       171 
225 
     | 
    
         | 
| 
      
 226 
     | 
    
         
            +
            # Matrix Int -> Int -> Int -> Int
         
     | 
| 
       172 
227 
     | 
    
         
             
            def nth2(i, j, xss):
         
     | 
| 
       173 
228 
     | 
    
         
             
              nth(j - 1, nth(i - 1, xss))
         
     | 
| 
       174 
229 
     | 
    
         | 
| 
      
 230 
     | 
    
         
            +
            # Partial; requires k to be in the map.
         
     | 
| 
      
 231 
     | 
    
         
            +
            # Int -> List (Int, b) -> b
         
     | 
| 
       175 
232 
     | 
    
         
             
            def lookup(k, []):
         
     | 
| 
       176 
233 
     | 
    
         
             
              error("Key not found in map")
         
     | 
| 
       177 
234 
     | 
    
         
             
            def lookup(k, (k_, v) :| kvs):
         
     | 
| 
       178 
235 
     | 
    
         
             
              if k == k_: v
         
     | 
| 
       179 
236 
     | 
    
         
             
              else: lookup(k, kvs)
         
     | 
| 
       180 
237 
     | 
    
         | 
| 
      
 238 
     | 
    
         
            +
            # Int -> Int -> Int
         
     | 
| 
       181 
239 
     | 
    
         
             
            def max(n, m):
         
     | 
| 
       182 
240 
     | 
    
         
             
              if n > m: n
         
     | 
| 
       183 
241 
     | 
    
         
             
              else: m
         
     | 
| 
       184 
242 
     | 
    
         | 
| 
      
 243 
     | 
    
         
            +
            # Int -> Int -> Int
         
     | 
| 
       185 
244 
     | 
    
         
             
            def min(n, m):
         
     | 
| 
       186 
245 
     | 
    
         
             
              if n < m: n
         
     | 
| 
       187 
246 
     | 
    
         
             
              else: m
         
     | 
| 
       188 
247 
     | 
    
         | 
| 
      
 248 
     | 
    
         
            +
            # List Int -> Int
         
     | 
| 
       189 
249 
     | 
    
         
             
            def maximum: foldr1(max)
         
     | 
| 
       190 
250 
     | 
    
         | 
| 
      
 251 
     | 
    
         
            +
            # List Int -> Int
         
     | 
| 
       191 
252 
     | 
    
         
             
            def minimum: foldr1(min)
         
     | 
| 
       192 
253 
     | 
    
         | 
| 
      
 254 
     | 
    
         
            +
            # List (a, b) -> (List a, List b)
         
     | 
| 
       193 
255 
     | 
    
         
             
            def unzip([]): ([], [])
         
     | 
| 
       194 
256 
     | 
    
         
             
            def unzip((x, y) :| zs):
         
     | 
| 
       195 
257 
     | 
    
         
             
              def (xs, ys): unzip(zs)
         
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
258 
     | 
    
         
             
              (x :| xs, y :| ys)
         
     | 
| 
       198 
259 
     | 
    
         | 
| 
      
 260 
     | 
    
         
            +
            # (a -> b -> c) -> List a -> List b -> List c
         
     | 
| 
       199 
261 
     | 
    
         
             
            def zipWith(op, [], ys): []
         
     | 
| 
       200 
262 
     | 
    
         
             
            def zipWith(op, x :| xs, []): []
         
     | 
| 
       201 
263 
     | 
    
         
             
            def zipWith(op, x :| xs, y :| ys):
         
     | 
| 
       202 
264 
     | 
    
         
             
              op(x, y) :| zipWith(op, xs, ys)
         
     | 
| 
       203 
265 
     | 
    
         | 
| 
      
 266 
     | 
    
         
            +
            # List a -> List b -> List (a, b)
         
     | 
| 
       204 
267 
     | 
    
         
             
            def zip: zipWith(curry(id))
         
     | 
| 
       205 
268 
     | 
    
         | 
| 
      
 269 
     | 
    
         
            +
            # Rename to 'range'
         
     | 
| 
      
 270 
     | 
    
         
            +
            # Int -> Int -> List Int
         
     | 
| 
       206 
271 
     | 
    
         
             
            def enumFromTo(n, m):
         
     | 
| 
       207 
272 
     | 
    
         
             
              if n <= m: n :| [n + 1 .. m]
         
     | 
| 
       208 
273 
     | 
    
         
             
              else: []
         
     | 
| 
       209 
274 
     | 
    
         | 
| 
      
 275 
     | 
    
         
            +
            # Rename to 'range2'
         
     | 
| 
      
 276 
     | 
    
         
            +
            # (Int, Int) -> (Int, Int) -> List (Int, Int)
         
     | 
| 
       210 
277 
     | 
    
         
             
            def range((m1, n1), (m2, n2)):
         
     | 
| 
       211 
278 
     | 
    
         
             
              [(i1, i2) for i1 in [m1 .. m2] for i2 in [n1 .. n2]]
         
     | 
| 
       212 
279 
     | 
    
         | 
| 
      
 280 
     | 
    
         
            +
            # Int -> Int -> Int
         
     | 
| 
       213 
281 
     | 
    
         
             
            def abs(x, y):
         
     | 
| 
       214 
282 
     | 
    
         
             
              if x - y < 0: negate(x - y)
         
     | 
| 
       215 
283 
     | 
    
         
             
              else: x - y
         
     | 
| 
       216 
284 
     | 
    
         | 
| 
      
 285 
     | 
    
         
            +
            # Eq a => [a] -> [a]
         
     | 
| 
       217 
286 
     | 
    
         
             
            def nub(xs):
         
     | 
| 
       218 
287 
     | 
    
         
             
              def nub_([], _): []
         
     | 
| 
       219 
288 
     | 
    
         
             
              def nub_(x :| xs, ys):
         
     | 
| 
         @@ -223,9 +292,11 @@ def nub(xs): 
     | 
|
| 
       223 
292 
     | 
    
         | 
| 
       224 
293 
     | 
    
         
             
              nub_(xs, [])
         
     | 
| 
       225 
294 
     | 
    
         | 
| 
      
 295 
     | 
    
         
            +
            # Int -> Int -> [a] -> [a]
         
     | 
| 
       226 
296 
     | 
    
         
             
            def slice(begin, end, xs):
         
     | 
| 
       227 
297 
     | 
    
         
             
              take(end - begin, drop(begin, xs))
         
     | 
| 
       228 
298 
     | 
    
         | 
| 
      
 299 
     | 
    
         
            +
            # (a -> Boolean) -> List a -> (List a, List a)
         
     | 
| 
       229 
300 
     | 
    
         
             
            def splitOn(p, data):
         
     | 
| 
       230 
301 
     | 
    
         
             
              def go(fls, trs, []):
         
     | 
| 
       231 
302 
     | 
    
         
             
                (reverse(fls), reverse(trs))
         
     | 
| 
         @@ -1,53 +1,50 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            def split([]): ([], [])
         
     | 
| 
       2 
2 
     | 
    
         
             
            def split(x :| xs):
         
     | 
| 
       3 
     | 
    
         
            -
              def (ys, zs): split(xs) 
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
              (x :| zs, ys);
         
     | 
| 
      
 3 
     | 
    
         
            +
              def (ys, zs): split(xs)
         
     | 
| 
      
 4 
     | 
    
         
            +
              (x :| zs, ys)
         
     | 
| 
       6 
5 
     | 
    
         | 
| 
       7 
6 
     | 
    
         
             
            def merge(xs, ys):
         
     | 
| 
       8 
7 
     | 
    
         
             
              match (xs, ys):
         
     | 
| 
       9 
8 
     | 
    
         
             
                case ([], _): ys
         
     | 
| 
       10 
     | 
    
         
            -
                case (x :|  
     | 
| 
       11 
     | 
    
         
            -
                case (x :|  
     | 
| 
       12 
     | 
    
         
            -
                  if x < y: x :| merge( 
     | 
| 
       13 
     | 
    
         
            -
                  else: y :| merge(xs,  
     | 
| 
      
 9 
     | 
    
         
            +
                case (x :| xs_, []): xs
         
     | 
| 
      
 10 
     | 
    
         
            +
                case (x :| xs_, y :| ys_):
         
     | 
| 
      
 11 
     | 
    
         
            +
                  if x < y: x :| merge(xs_, ys)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  else: y :| merge(xs, ys_)
         
     | 
| 
       14 
13 
     | 
    
         | 
| 
       15 
14 
     | 
    
         
             
            def mergesort(xs):
         
     | 
| 
       16 
15 
     | 
    
         
             
              if length(xs) < 2: xs
         
     | 
| 
       17 
16 
     | 
    
         
             
              else:
         
     | 
| 
       18 
     | 
    
         
            -
                def (ys, zs): split(xs) 
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                merge(mergesort(ys), mergesort(zs));
         
     | 
| 
      
 17 
     | 
    
         
            +
                def (ys, zs): split(xs)
         
     | 
| 
      
 18 
     | 
    
         
            +
                merge(mergesort(ys), mergesort(zs))
         
     | 
| 
       21 
19 
     | 
    
         | 
| 
       22 
20 
     | 
    
         
             
            def findQuantile(q, p, xs):
         
     | 
| 
       23 
21 
     | 
    
         
             
              def rank:
         
     | 
| 
       24 
22 
     | 
    
         
             
                (p / q) * (length(xs) - 1);
         
     | 
| 
       25 
23 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
              if rank == floor(rank): 
     | 
| 
      
 24 
     | 
    
         
            +
              if rank == floor(rank):
         
     | 
| 
      
 25 
     | 
    
         
            +
                nth(rank, xs)
         
     | 
| 
       27 
26 
     | 
    
         
             
              else:
         
     | 
| 
       28 
27 
     | 
    
         
             
                def x1: floor(rank)
         
     | 
| 
       29 
28 
     | 
    
         
             
                def x2: ceiling(rank)
         
     | 
| 
       30 
29 
     | 
    
         
             
                def left: nth(x1, xs)
         
     | 
| 
       31 
     | 
    
         
            -
                def right: nth(x2, xs) 
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                left + (rank - x1) * (right - left);
         
     | 
| 
      
 30 
     | 
    
         
            +
                def right: nth(x2, xs)
         
     | 
| 
      
 31 
     | 
    
         
            +
                left + (rank - x1) * (right - left)
         
     | 
| 
       34 
32 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
            def findPercentile: findQuantile(100) 
     | 
| 
      
 33 
     | 
    
         
            +
            def findPercentile: findQuantile(100)
         
     | 
| 
       36 
34 
     | 
    
         | 
| 
       37 
35 
     | 
    
         
             
            def accumBins(data, Nil): []
         
     | 
| 
       38 
36 
     | 
    
         
             
            def accumBins(data, [l]): []
         
     | 
| 
       39 
37 
     | 
    
         
             
            def accumBins(data, l :| r :| es):
         
     | 
| 
       40 
38 
     | 
    
         
             
              def (ge, le):
         
     | 
| 
       41 
     | 
    
         
            -
                splitOn((lambda x: x <= r), data) 
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
              (le, r - l) :| accumBins(ge, r :| es);
         
     | 
| 
      
 39 
     | 
    
         
            +
                splitOn((lambda x: x <= r), data)
         
     | 
| 
      
 40 
     | 
    
         
            +
              (le, r - l) :| accumBins(ge, r :| es)
         
     | 
| 
       44 
41 
     | 
    
         | 
| 
       45 
42 
     | 
    
         
             
            def cut(xs, nbins):
         
     | 
| 
       46 
43 
     | 
    
         
             
              def low: minimum(xs)
         
     | 
| 
       47 
44 
     | 
    
         
             
              def binwidth:
         
     | 
| 
       48 
45 
     | 
    
         
             
                (maximum(xs) - low) / nbins
         
     | 
| 
       49 
46 
     | 
    
         
             
              def edges:
         
     | 
| 
       50 
     | 
    
         
            -
                [low + x * binwidth for x in enumFromTo(0, nbins)] 
     | 
| 
      
 47 
     | 
    
         
            +
                [low + x * binwidth for x in enumFromTo(0, nbins)]
         
     | 
| 
       51 
48 
     | 
    
         | 
| 
       52 
49 
     | 
    
         
             
              accumBins(xs, edges);
         
     | 
| 
       53 
50 
     | 
    
         | 
| 
         @@ -55,32 +52,32 @@ def qcut(xs, qs): 
     | 
|
| 
       55 
52 
     | 
    
         
             
              def (low, high):
         
     | 
| 
       56 
53 
     | 
    
         
             
                (minimum(xs), maximum(xs))
         
     | 
| 
       57 
54 
     | 
    
         
             
              def edges:
         
     | 
| 
       58 
     | 
    
         
            -
                append((low :| [findPercentile(x, xs) for x in qs], [high])) 
     | 
| 
      
 55 
     | 
    
         
            +
                append((low :| [findPercentile(x, xs) for x in qs], [high]))
         
     | 
| 
       59 
56 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
              accumBins(xs, edges) 
     | 
| 
      
 57 
     | 
    
         
            +
              accumBins(xs, edges)
         
     | 
| 
       61 
58 
     | 
    
         | 
| 
       62 
59 
     | 
    
         
             
            def likelihoodLE(xs, target):
         
     | 
| 
       63 
     | 
    
         
            -
              length(filter((lambda x: x <= target), xs)) / length(xs) 
     | 
| 
      
 60 
     | 
    
         
            +
              length(filter((lambda x: x <= target), xs)) / length(xs)
         
     | 
| 
       64 
61 
     | 
    
         | 
| 
       65 
62 
     | 
    
         
             
            def likelihoodGE(xs, target):
         
     | 
| 
       66 
     | 
    
         
            -
              length(filter((lambda x: x >= target), xs)) / length(xs) 
     | 
| 
      
 63 
     | 
    
         
            +
              length(filter((lambda x: x >= target), xs)) / length(xs)
         
     | 
| 
       67 
64 
     | 
    
         | 
| 
       68 
65 
     | 
    
         
             
            def likelihoodMap(table, prob):
         
     | 
| 
       69 
     | 
    
         
            -
              fromSome(find((lambda x: x.prob <= prob), table)).msg 
     | 
| 
      
 66 
     | 
    
         
            +
              fromSome(find((lambda x: x.prob <= prob), table)).msg
         
     | 
| 
       70 
67 
     | 
    
         | 
| 
       71 
68 
     | 
    
         
             
            def mkPercent(num):
         
     | 
| 
       72 
     | 
    
         
            -
              numToStr(num * 100) ++ "%" 
     | 
| 
      
 69 
     | 
    
         
            +
              numToStr(num * 100) ++ "%"
         
     | 
| 
       73 
70 
     | 
    
         | 
| 
       74 
71 
     | 
    
         
             
            def leqP(n, m):
         
     | 
| 
       75 
72 
     | 
    
         
             
              if n <= m: "less"
         
     | 
| 
       76 
     | 
    
         
            -
              else: "more" 
     | 
| 
      
 73 
     | 
    
         
            +
              else: "more"
         
     | 
| 
       77 
74 
     | 
    
         | 
| 
       78 
75 
     | 
    
         
             
            def gradedLeqP(n, m):
         
     | 
| 
       79 
     | 
    
         
            -
              def ratio: n / m 
     | 
| 
      
 76 
     | 
    
         
            +
              def ratio: n / m
         
     | 
| 
       80 
77 
     | 
    
         | 
| 
       81 
78 
     | 
    
         
             
              if ratio <= 1.0:
         
     | 
| 
       82 
79 
     | 
    
         
             
                if ratio <= 0.5: "much less"
         
     | 
| 
       83 
80 
     | 
    
         
             
                else: "less"
         
     | 
| 
       84 
81 
     | 
    
         
             
              else:
         
     | 
| 
       85 
82 
     | 
    
         
             
                if ratio >= 2.0: "much more"
         
     | 
| 
       86 
     | 
    
         
            -
                else: "more" 
     | 
| 
      
 83 
     | 
    
         
            +
                else: "more"
         
     |