-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding SignalList(SList) and SignalTree. QuickSort for SList.
Fix a bug with caching that required a new state INITIAL. Add debug global flag so that one can dump the state of a signal, in the read callback without throwing. Adding debugName as part of external inteface.
- Loading branch information
Showing
8 changed files
with
180 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import {input} from '.'; | ||
import {fromArray, toArray} from './slist'; | ||
import {qsort, filter} from './qsort'; | ||
|
||
test('basic filter', () => { | ||
const list = fromArray([1, 2, 3]); | ||
const filtered = filter(list, x => x % 2 === 0); | ||
expect(toArray(filtered)).toEqual([2]); | ||
}); | ||
|
||
test('filter reacts to mutations', () => { | ||
const list = fromArray([1, 2, 3]); | ||
const filtered = filter(list, x => x % 2 === 0); | ||
// mutating value at head | ||
// new list [4, 2, 3] | ||
list.value = {value: 4, tail: list.value!.tail}; | ||
expect(toArray(filtered)).toEqual([4, 2]); | ||
}); | ||
|
||
test('it sorts', () => { | ||
const list = fromArray([3, 1, 2]); | ||
const sorted = qsort(list); | ||
expect(toArray(sorted)).toEqual([1, 2, 3]); | ||
}); | ||
|
||
test('it reacts to changes in number', () => { | ||
const list = fromArray([3, 1, 2]); | ||
const sorted = qsort(list); | ||
|
||
// mutating a value in the front | ||
// new list [0, 1, 2] | ||
list.value = {value: 0, tail: list.value!.tail}; | ||
expect(toArray(sorted)).toEqual([0, 1, 2]); | ||
|
||
// mutating a value in the middle | ||
// new list [0, 3, 2] | ||
list.value!.tail.value = {value: 3, tail: list.value!.tail.value!.tail}; | ||
expect(toArray(sorted)).toEqual([0, 2, 3]); | ||
|
||
}); | ||
|
||
test('it reacts to appending new values', () => { | ||
const list = fromArray([3, 1, 2]); | ||
const sorted = qsort(list); | ||
|
||
// appending a new value; | ||
// new list [3, 4, 1, 2] | ||
const mid = list.value!.tail; | ||
list.value = {value: list.value!.value, tail: input({value: 4, tail: mid})}; | ||
expect(toArray(sorted)).toEqual([1, 2, 3, 4]); | ||
}); | ||
|
||
test('it reacts to removing part of the list', () => { | ||
const list = fromArray([3, 1, 2]); | ||
const sorted = qsort(list); | ||
|
||
// removing part of the list starting in the middle | ||
// new list [3, 0] | ||
list.value!.tail.value = {value: 0, tail: input(null)}; | ||
expect(toArray(sorted)).toEqual([0, 3]); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import {input} from '.'; | ||
import {SList, toArray} from './slist'; | ||
|
||
export function filter<T>(slist: SList<T>, pred: (x: T) => boolean): SList<T> { | ||
return slist.read(list => { | ||
if (!list) { | ||
return input(null); | ||
} | ||
const rest = filter(list.tail, pred); | ||
return pred(list.value) ? input({value: list.value, tail: rest}) : rest; | ||
}); | ||
} | ||
|
||
export function qsort<T>(slist: SList<T>, rest?: SList<T>): SList<T> { | ||
return slist.read(list => { | ||
if (list === null) { | ||
return rest ? rest : input(null); | ||
} | ||
const pivot = list.value; | ||
const left = filter(list.tail, x => x < pivot); | ||
const right = filter(list.tail, x => x >= pivot); | ||
const half = input({value: pivot, tail: qsort(right, rest)}); | ||
return qsort(left, half); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import {input, Signal} from '.'; | ||
import {fromArray, toArray, SList} from './slist'; | ||
|
||
test('basic slist', () => { | ||
const list = fromArray([1, 2, 3]); | ||
expect(toArray(list)).toEqual([1, 2, 3]); | ||
}); | ||
|
||
test('slist sum', () => { | ||
const list = fromArray([1, 2, 3]); | ||
function sum(list: SList<number>): Signal<number> { | ||
return list.read(list => list ? sum(list.tail).read(rest => rest + list.value) : 0); | ||
} | ||
const s = sum(list); | ||
expect(s.value).toBe(6); | ||
// mutate value at head | ||
list.value = {value: 4, tail: list.value!.tail}; | ||
expect(s.value).toBe(9); | ||
|
||
// mutate value in the middle | ||
|
||
list.value.tail.value = {value: 0, tail: list.value.tail.value!.tail}; | ||
expect(s.value).toBe(7); | ||
|
||
// mutate at tail | ||
list.value = {value: 5, tail: input(null)}; | ||
expect(s.value).toBe(5); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import {input} from '.'; | ||
import type {Input} from '.'; | ||
|
||
interface Node<T> { | ||
value: T; | ||
tail: SList<T>; | ||
} | ||
|
||
export type SList<T> = Input<Node<T>|null>; | ||
|
||
export function fromArray<T>(arr: T[]): SList<T> { | ||
if (arr.length === 0) { | ||
return input(null); | ||
} | ||
const [head, ...tail] = arr; | ||
return input({value: head, tail: fromArray(tail)}); | ||
} | ||
|
||
export function toArray<T>(list: SList<T>): T[] { | ||
const arr: T[] = []; | ||
while (list.value) { | ||
arr.push(list.value.value); | ||
list = list.value.tail; | ||
} | ||
return arr; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import type {Signal} from '.'; | ||
|
||
export type IncrTree<T> = Signal<TreeNode<T> | null>; | ||
interface TreeNode<T> { | ||
readonly value: T; | ||
readonly left: IncrTree<T>; | ||
readonly right: IncrTree<T>; | ||
} |