-
Notifications
You must be signed in to change notification settings - Fork 0
/
Foreign.Data.Array.NonEmpty.Internal.kt
65 lines (64 loc) · 2.01 KB
/
Foreign.Data.Array.NonEmpty.Internal.kt
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
@file:Suppress("UNCHECKED_CAST")
package Foreign.Data.Array.NonEmpty.Internal
val fold1Impl = { f: Any ->
{ ls: Any ->
ls as List<Any>; f as (Any) -> ((Any) -> Any)
var acc = ls[0]
ls.forEach {
acc = f(acc)(it)
}
acc
}
}
data class Cont(val fn: () -> Any)
data class ConsCell(val head: Any, val tail: Any)
val traverse1Impl = {
val emptyList = Unit
val finalCell = {head: Any -> ConsCell(head, emptyList)}
val consList = {x: Any -> {xs: Any -> ConsCell(x, xs)}}
fun listToArray(list: ConsCell): List<Any> {
var arr = mutableListOf<Any>()
var xs = list
while (true) {
arr.add(xs.head)
val tail = xs.tail
if (tail is ConsCell) {
xs = tail
} else {
return arr
}
}
}
{ apply: Any ->
{ map: Any ->
{ f: Any ->
apply as (Any) -> ((Any) -> ((Any) -> Any))
map as (Any) -> ((Any) -> ((Any) -> Any))
f as (Any) -> Any
val buildFrom = { x: Any, ys: Any ->
apply(map(consList)(f(x)))(ys)
}
fun go(acc: Any, currentLen: Int, xs: List<Any>) {
when (currentLen) {
0 -> acc
else -> {
val last = xs.last()
Cont {
go(buildFrom(last, acc), currentLen - 1, xs)
}
}
}
}
{ array: Any ->
array as List<Any>
val acc = map(finalCell)(f(array[array.size - 1]))
var result : Any = go(acc, array.size -1, array)
while (result is Cont) {
result = result.fn()
}
map(::listToArray)(result)
}
}
}
}
}