Last active
February 18, 2017 16:07
-
-
Save samwgoldman/1fcceea36206e1544414 to your computer and use it in GitHub Desktop.
Maybe type in JS/Flow
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
/* @flow */ | |
type Maybe<T,U> = (pattern: { | |
some(x: T): U; | |
none(): U; | |
}) => U; | |
function map<A,B,C>(maybe: Maybe<A,C>, f: (a: A) => B): Maybe<B,C> { | |
return function(pattern) { | |
return maybe({ | |
some: (a) => pattern.some(f(a)), | |
none: pattern.none | |
}); | |
} | |
} | |
function flatMap<A,B,C>(maybe: Maybe<A,C>, f: (a: A) => Maybe<B,C>): Maybe<B,C> { | |
return function(pattern) { | |
return maybe({ | |
some: (a) => f(a)(pattern), | |
none: pattern.none | |
}) | |
} | |
} | |
function safeLookup<T,U>(object: { [key: string]: T }, key: string): Maybe<T,U> { | |
return function(pattern) { | |
var value = object[key]; | |
if (typeof value === "undefined") { | |
return pattern.none(); | |
} else { | |
return pattern.some(value); | |
} | |
} | |
} | |
function safeParseInt<U>(input: string, radix?: number): Maybe<number,U> { | |
return function(pattern) { | |
var result = parseInt(input, radix); | |
if (isNaN(result)) { | |
return pattern.none(); | |
} else { | |
return pattern.some(result); | |
} | |
} | |
} | |
// Utils | |
function identity<T>(x: T): T { | |
return x; | |
} | |
type Constant<T> = () => T; | |
function constant<T>(x: T): Constant<T> { | |
return () => x; | |
} | |
// Examples | |
var ex1: number | string = safeParseInt("10")({ | |
some: identity, | |
none: constant("oops!") | |
}); | |
var ex2: Maybe<number, mixed> = map(safeParseInt("10"), (n) => n * 2) | |
var ex3: Maybe<number, mixed> = flatMap(safeLookup({ foo: "123" }, "foo"), safeParseInt); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment