-
Notifications
You must be signed in to change notification settings - Fork 0
/
addition.nim
55 lines (28 loc) · 1001 Bytes
/
addition.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 `Addition` monoid for integers.
| Type `T` | Operation | Neutral element |
| --- | --- | --- |
| Any integer | `+` | `0` |
]##
import ../../misc/[int_concept_predicates]
import pkg/funcynim/[convert, into]
import std/[sugar]
type
ValidInteger* {.explain.} = concept type X of SomeInteger ##[
Represents any integer type eligible for the `Addition` monoid.
The integer type must include `0` in its range.
]##
0 in X
Addition*[T: ValidInteger] = distinct T
proc addition*[T](value: T): Addition[T] =
value.to(Addition[T])
proc unbox*[T](self: Addition[T]): T =
self.to(T)
proc `==`*[T](left, right: Addition[T]): bool =
left.unbox() == right.unbox()
proc map*[A; B](self: Addition[A]; f: A -> B): Addition[B] =
self.unbox().into(f).addition()
proc neutral*[T](X: typedesc[Addition[T]]): X =
0.to(T).addition()
proc fold*[T](left, right: Addition[T]): Addition[T] =
left.map(l => l.`+`(right.unbox()).to(T))