type Row { name: Text count: Int } type Problem { error Denied(value: Int) } type Result { Ready(value: Int) error Failed(problem: Problem) } type Ack { Done error Failed(problem: Problem) } checked(value: Int < 0) (answer: Int) { fail(Problem.Denied(value)) } checked(value: other) (answer: Int) { answer = value } increment(value: Int) (answer: Int) pure { answer = value + 1 } decrement(value: Int) (answer: Int) pure { answer = value - 1 } apply(route: handler(value: Int) (answer: Int), value: Int) (answer: Int) { answer = route(value) } forward(route: handler(value: Int) (answer: Int), value: Int) (answer: Int) { answer = apply(route, value) } compose(first: handler(value: Int) (answer: Int), value: Int, second: handler(value: Int) (answer: Int)) (answer: Int) { answer = apply(second, apply(first, value)) } mapAll(route: handler(value: Int) (answer: Int), values: List) (answers: List) { answers = each(route, values) } mapForward(route: handler(value: Int) (answer: Int), values: List) (answers: List) { answers = mapAll(route, values) } sumForward(route: handler(value: Int) (answer: Int), values: List) (answer: Int) { answer = sum(route, values) } foldForward(route: handler(value: Int, state: Int) (next: Int), values: List) (answer: Int) { answer = reduce(route, values, 0) } add(value: Int, state: Int) (next: Int) { next = state + value } append(value: Text) (answer: Text) { answer = value + "新" } textApply(route: handler(value: Text) (answer: Text), value: Text) (answer: Text) { answer = route(value) } change(row: Row) (answer: Row) { answer = row answer.name = row.name + "新" answer.count = row.count + 1 } rowsForward(route: handler(value: Row) (answer: Row), values: List) (answers: List) { answers = each(route, values) } pair(value: Int) (first: Int, second: Int) { first = value second = value + 1 } pairForward(route: handler(value: Int) (first: Int, second: Int), value: Int) (answer: Int) { pair = route(value) answer = pair.first + pair.second } action(route: handler(value: Int) (), value: Int) () { route(value) } discard(value: Int) () { } capture(route: handler(value: Int) (answer: Int), value: Int) (answer: Result) { answer = result(route(value)) } captureAction(route: handler(value: Int) (), value: Int) (answer: Ack) { answer = result(route(value)) } checkedAction(value: Int) () { number = checked(value) } seed() (answer: Int) { answer = 42 } runOnce(route: handler() (answer: Int)) (answer: Int) { answer = route() } integerEntry(value: Int) (answer: Int) pure { answer = forward(increment, value) } mapEntry(values: List) (answer: List) pure { answer = mapForward(increment, values) } foldEntry(values: List) (answer: Int) pure { answer = foldForward(add, values) } textEntry(value: Text) (answer: Text) pure { answer = textApply(append, value) } rowsEntry(values: List) (answer: List) pure { answer = rowsForward(change, values) } captureEntry(value: Int) (answer: Result) pure { answer = capture(checked, value) } verify() (answer: Bool) recover("compare captured handler failures with expected values") { up = forward(increment, 4) down = forward(decrement, 4) original = Row { name = "雪" count = 2 } changed = rowsEntry([original]) action(discard, 1) answer = up == 5 and down == 3 and compose(increment, 10, decrement) == 10 answer = answer and mapEntry([1, 2]) == [2, 3] and length(mapEntry([])) == 0 and foldEntry([1, 2, 3]) == 6 answer = answer and textEntry("雪") == "雪新" and pairForward(pair, 3) == 7 and runOnce(seed) == 42 answer = answer and changed == [Row { name = "雪新" count = 3 }] and original.name == "雪" and original.count == 2 answer = answer and captureEntry(5) == Result.Ready(5) and captureEntry(-1) == Result.Failed(Problem.Denied(-1)) answer = answer and captureAction(discard, 0) == Ack.Done and captureAction(checkedAction, -2) == Ack.Failed(Problem.Denied(-2)) } failureEntry() (answer: Int) { answer = forward(checked, -3) } faultEntry() (answer: Result) { answer = capture(increment, 9223372036854775807) } argumentEntry() (answer: Result) { answer = capture(increment, checked(-4)) } collectionEntry() (answer: Int) { answer = sumForward(checked, [1, -5, 3]) }