-
Notifications
You must be signed in to change notification settings - Fork 0
/
junction.nim
55 lines (27 loc) · 1016 Bytes
/
junction.nim
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
##[
This module implements the `Junction` monoid (a.k.a. `Concatenation`) for
linear data structures such as `seq[T]`, `string`, or linked lists.
| Type `T` | Operation | Neutral element |
| --- | --- | --- |
| Any linear data structure | `&` | The empty `T` |
]##
import pkg/funcynim/[convert, into]
import std/[sugar]
type
Joinable* = concept type X
proc `&`(left, right: X): X
Junction*[T: Joinable] = distinct T
proc junction*[T](self: T): Junction[T] =
self.to(Junction[T])
proc unbox*[T](self: Junction[T]): T =
self.to(T)
proc `==`*[T](left, right: Junction[T]): bool =
left.unbox() == right.unbox()
proc map*[A; B](self: Junction[A]; f: A -> B): Junction[B] =
self.unbox().into(f).junction()
proc neutral*(X: typedesc[Junction[string]]): X =
string.default().junction()
proc neutral*[T](X: typedesc[Junction[seq[T]]]): X =
seq[T].default().junction()
proc fold*[T](left, right: Junction[T]): Junction[T] =
left.map(l => l.`&`(right.unbox()).to(T))