Skip to content

Commit e2c987f

Browse files
authored
group-by, qsort et al (#183)
- Added some experimental prelude functions `group-by`, `discriminate`, `fnil`, `qsort`.
1 parent 8452c67 commit e2c987f

File tree

5 files changed

+77
-0
lines changed

5 files changed

+77
-0
lines changed

harness/test/052_group_by.eu

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"Tests for prelude `group-by`"
2+
3+
class(n): if(n < 5, :small, :big)
4+
5+
tests: {
6+
α: [2, 4, 6, 8, 7] group-by(class) //= { small: [2, 4], big: [6, 8, 7] }
7+
β: ["red", "yellow", "ruby", "rose", "blue", "beryl"]
8+
group-by(sym ∘ first ∘ str.letters)
9+
map-values(count)
10+
//= { r: 3 y: 1 b: 2}
11+
γ: [] group-by(identity) //= {}
12+
}
13+
14+
RESULT: tests values all-true? then(:PASS, :FAIL)

harness/test/053_discriminate.eu

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"Tests for prelude `discriminate`"
2+
3+
tests: {
4+
α: [3, 6, 8, 7, 4] discriminate(_ < 6) //= [[3, 4], [6, 8, 7]]
5+
β: [] discriminate(pos?) //= [[], []]
6+
γ: [-32, 32, -64, 64, 0] discriminate(pos?) //= [[32, 64], [-32, -64, 0]]
7+
}
8+
9+
RESULT: tests values all-true? then(:PASS, :FAIL)

harness/test/054_qsort.eu

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
"Tests for prelude `qsort`."
2+
3+
tests: {
4+
α: [7,3,4,7,1,9] qsort(<) //= [1, 3, 4, 7, 7, 9]
5+
β: [] qsort(<) //= []
6+
γ: null fnil(qsort(<), []) //= []
7+
δ: ["one", "two", "three", "four", "five", "six"]
8+
qsort({ lhs: • rhs: • }.( (lhs str.letters count) < (rhs str.letters count) ))
9+
//= ["one", "two", "six", "four", "five", "three"]
10+
}
11+
12+
RESULT: tests values all-true? then(:PASS, :FAIL)

lib/prelude.eu

+27
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,11 @@ cond(l, d): l foldr(uncurry(if), d)
436436
` "`juxt(f, g) - return function of `x` returning list of `f(x)` and g(x)`."
437437
juxt(f, g, x): [x f, x g]
438438

439+
#
440+
# Utilities
441+
#
442+
` "`fnil(f, v, x)` - return a function equivalent to f except it sees `x` instead of `null` when null is passed."
443+
fnil(f, v, x): if(x = null, f(v), f(x))
439444

440445
#
441446
# Metadata basics
@@ -645,6 +650,28 @@ over-sliding-pairs(f, l): l window(2, 1) map(f uncurry)
645650
` "differences(l) - calculate difference between each overlapping pair in list of numbers `l`"
646651
differences: over-sliding-pairs(_1 - _0)
647652

653+
` "`discriminate(pred, xs)` - return pair of `xs` for which `pred(_)` is true and `xs` for which `pred(_)` is false."
654+
discriminate(pred, xs): {
655+
acc(a, e): a if(e pred, bimap(cons(e), identity), bimap(identity, cons(e)))
656+
}.(xs foldl(acc, [[], []]) bimap(reverse, reverse))
657+
658+
` "`group-by(k, xs)` - group xs by key function returning block of key to subgroups, maintains order."
659+
group-by(k, xs): {
660+
acc(a, e): a update-value-or(e._k, cons(e._v), [e._v])
661+
}.(xs map({ _k: k(•0), _v: •0 }) foldl(acc, {}) map-values(reverse))
662+
663+
` "`qsort(lt, xs)` - sort `xs` using 'less-than' function `lt`"
664+
qsort(lt, xs): if(xs nil?,
665+
xs,
666+
{
667+
h: xs head
668+
t: xs tail
669+
less(x): lt(x, h)
670+
partitions: t discriminate(less)
671+
smaller: partitions first qsort(lt)
672+
bigger: partitions second qsort(lt)
673+
}.(smaller ++ [h] ++ bigger))
674+
648675
#
649676
# Block library functions
650677
#

tests/harness_test.rs

+15
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,18 @@ pub fn test_harness_050() {
250250
pub fn test_harness_051() {
251251
run_test(&opts("051_head_or.eu"));
252252
}
253+
254+
#[test]
255+
pub fn test_harness_052() {
256+
run_test(&opts("052_group_by.eu"));
257+
}
258+
259+
#[test]
260+
pub fn test_harness_053() {
261+
run_test(&opts("053_discriminate.eu"));
262+
}
263+
264+
#[test]
265+
pub fn test_harness_054() {
266+
run_test(&opts("054_qsort.eu"));
267+
}

0 commit comments

Comments
 (0)