Skip to content

Instantly share code, notes, and snippets.

@jahan-addison
Last active November 28, 2016 23:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jahan-addison/62d2a4a6032b325bc0a81fdba9be7f63 to your computer and use it in GitHub Desktop.
Save jahan-addison/62d2a4a6032b325bc0a81fdba9be7f63 to your computer and use it in GitHub Desktop.
// Copyright (c) 2016, Jahan Addison
// License: MIT
// @version: 1.2.0
type Tuple<T> = [T];
type Pure<T> = (T: T) => T;
type Pattern = string | number;
type Invoker = Pure<Pattern>;
type Val = Tuple<Pattern>;
type Case = boolean;
interface Matchable {
case (x: Case, g: Invoker): Match;
pattern (x: Pattern, g: Invoker): Match;
_(g: Invoker): Pattern;
}
// identity :: (Matchable a) => a -> a
function identity<T>(_: T) {
return _;
}
// Eq :: Value -> Value -> bool
function Eq(e: Value, f: Value) {
return e.x[0] === f.x[0];
}
// Read :: Value -> Val
function Read(e: Value) {
return e.x;
}
// instance Functor Val where
// fmap = map
class Value {
constructor(x: Val) {
this.x = x;
}
public map(g: Invoker) {
return new Value(
this.x.map(g) as Val
);
}
x: Val;
}
export class Match implements Matchable {
constructor(x: Pattern) {
this.x = x;
this.map = 0;
this.value = new Value([x]);
}
public pattern(x: Pattern, g: Invoker): Match {
if (Eq(new Value([x]), this.value)) {
this.map++;
this.value = this.value.map(g);
}
return this;
}
public case(x: Case, g: Invoker): Match {
if (x) {
this.map++;
this.value = this.value.map(g);
}
return this;
}
public _(g: Invoker = identity): Pattern {
if(!this.map) this.value = this.value.map(g);
return Read(this.value)[0];
}
x: Pattern;
value: Value;
map: number;
get val(): Pattern {
return this.x;
}
}
type Callback = ( _: Match, value: Pattern) => Pattern;
export function match(pattern: Pattern, g: Callback): Pattern {
const ref = new Match(pattern);
return g.call(ref, ref, ref.val);
}
/* Clamp:
const min = 200;
const max = 500;
const t = match(323, (_, v: number) => {
return _
.case(v < min, z => min)
.case(v < max, z => z)
._(z => max)
}); */
// t = 323
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment