Files
functional-programming-snake/js/src/io.js
T

44 lines
1.9 KiB
JavaScript

import { todo } from './todo.js'
/**
* Effects as values. An `IO<A>` is a description of a program that, when interpreted, produces an `A`:
* `{tag:'Pure', value}` - finished, nothing left to do
* `{tag:'Effect', op, k}` - perform `op`, then continue with `k(result)` (which returns another IO)
* Operations: `{tag:'Draw', shape}` (result `undefined`) and `{tag:'RandomSeed'}` (result: a uint32 number).
* Building an IO never performs anything; only an interpreter (`trace` here, `runIO` in m09) does.
*/
/** An IO that does nothing and produces `a`. */
export const pure = (a) => todo('m07')
/** An IO that performs the single operation `op` and produces its result: `{tag:'Effect', op, k: pure}`. */
export const effect = (op) => todo('m07')
/** Transform the result of `io` with `f`. Must not call `f` until the IO is interpreted. */
export const map = (io, f) => todo('m07')
/**
* Run `io`, then feed its result to `f` to get the next IO.
* Pure: `f(value)`. Effect(op, k): the same op, with the continuation extended by `f`.
*/
export const flatMap = (io, f) => todo('m07')
/** Run the IOs one after another, left to right, producing `undefined`. `sequence([])` performs nothing. */
export const sequence = (ios) => todo('m07')
/** An IO that draws one shape (a `Rect` or `Text` from m06). */
export const draw = (shape) => todo('m07')
/** An IO that asks the outside world for a random uint32 seed. A value, not a function. */
export const randomSeed = { get tag() { return todo('m07') } }
/** Draw every shape of a scene in order: `sequence(scene.map(draw))`. */
export const drawScene = (scene) => todo('m07')
/**
* A pure interpreter for tests. Answers every `RandomSeed` with `seed` and every `Draw` with `undefined`.
* Returns `{result, ops}`: the final value and the operations in the order they were executed.
* Implemented by recursion, with no mutation.
*/
export const trace = (io, seed) => todo('m07')