Created
January 5, 2016 18:14
-
-
Save jbrownson/2e9eebe0446a36c62a94 to your computer and use it in GitHub Desktop.
ADTs in Javascript using functions
This file contains hidden or 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
| export type Disjunction<T, U> = <Z>(a: (t: T) => Z, b: (u: U) => Z) => Z | |
| export type Disjunction3<T, U, V> = Disjunction<T, Disjunction<U, V>> | |
| export type Disjunction4<T, U, V, W> = Disjunction3<T, U, Disjunction<V, W>> | |
| export type List<T> = Disjunction<{head: T, tail: List<T>}, {}> | |
| export type Maybe<T> = Disjunction<T, {}> | |
| export function listFromArray<T>(array: T[]): List<T> { | |
| return <Z>(a: (x: {head: T, tail: List<T>}) => Z, b: () => Z) => | |
| array.length == 0 | |
| ? b() | |
| : a({head: array[0], tail: listFromArray(array.slice(1))}) } | |
| export const emptyList = <T, Z>(a: (x: {head: T, tail: List<T>}) => Z, b: () => Z) => b() | |
| export function prepend<T>(t: T, list: List<T>): List<T> { | |
| return <Z>(a: (x: {head: T, tail: List<T>}) => Z, b: () => Z) => a({head: t, tail: list}) } | |
| export function any<T>(predicate: (t: T) => boolean, list: List<T>): boolean { | |
| return list(({head, tail}) => predicate(head) || any(predicate, tail), () => false) } | |
| export function arrayFromList<T>(list: List<T>): T[] { | |
| return _arrayFromList(list, emptyList) } | |
| function _arrayFromList<T>(list: List<T>, seen: List<List<T>>): T[] { | |
| return list( | |
| ({head, tail}) => any(t => t === list, seen) | |
| ? [] | |
| : [head].concat(_arrayFromList(tail, prepend(list, seen))), | |
| () => []) } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment