Last active
August 17, 2016 03:53
-
-
Save justinvh/8917c0dbcb34131a5e98c096f590ed6f to your computer and use it in GitHub Desktop.
prelude-ideas
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
type MaybeIterator<T> = IterableIterator<T> | T[]; | |
function *iter<A>(a: A[]): IterableIterator<A> { | |
yield* a; | |
} | |
function isIter<A>(a: MaybeIterator<A>): a is IterableIterator<A> { | |
return (<IterableIterator<A>>a).next !== undefined; | |
} | |
function ensureIterable<A>(a: MaybeIterator<A>): IterableIterator<A> { | |
if (isIter<A>(a)) { | |
return a; | |
} else { | |
return iter<A>(a); | |
} | |
} | |
/** | |
* map | |
* (a -> b) -> [a] -> [b] | |
* returns a list constructed by appling a function (the first argument) to | |
* all items in a list passed as the second argument | |
*/ | |
function *map<A, B>(op: ((a: A) => B), a: MaybeIterator<A>): IterableIterator<B> { | |
for (let v of ensureIterable<A>(a)) { | |
yield op(v); | |
} | |
} | |
/** | |
* abs | |
* Num a => a -> a | |
* | |
* absolute vlaue of the number | |
*/ | |
function *abs(a: MaybeIterator<number>): IterableIterator<number> { | |
yield* map((p) => Math.abs(p), a); | |
} | |
/** | |
* zip | |
* [a] -> [b] -> [(a, b)] | |
* | |
* makes a list of tuples, each tuple containing elements of both lists ocurring | |
* at the same position. | |
* | |
* @see unzip unzip3 zip3 zipWith zipWith3 | |
*/ | |
function *zip<A, B>(a: MaybeIterator<A>, b: MaybeIterator<B>): IterableIterator<[A, B]> | |
{ | |
yield* zipWith(a, b, (l, r) => [l, r]); | |
} | |
/** | |
* unzip | |
* [(a, b)] -> ([a], [b]) | |
*/ | |
function unzip<A, B>(a: MaybeIterator<[A, B]>): [A[], B[]] | |
{ | |
let lhs: A[] = []; | |
let rhs: B[] = []; | |
for (let v of ensureIterable(a)) { | |
lhs.push(v[0]); | |
rhs.push(v[1]); | |
} | |
return [lhs, rhs]; | |
} | |
function *zipWith<A, B, C>(op: ((a: A, b: B) => C), | |
a: MaybeIterator<A>, | |
b: MaybeIterator<B>): IterableIterator<C> | |
{ | |
let lhs = ensureIterable(a); | |
let rhs = ensureIterable(b); | |
while (true) { | |
let l = lhs.next().value; | |
let r = rhs.next().value; | |
yield op(l, r); | |
} | |
} | |
console.log(zipWith((a: number, b: number) => a * b, [1, 2, 3], [4, 5, 6])); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment