Last active
February 19, 2024 19:20
-
-
Save zeusdeux/cb573186899f82571ae72e040c4e2755 to your computer and use it in GitHub Desktop.
Another Maybe and Either implementation in Typescript without making the value constructors (Just, Nothing, Left and Right) types themeselves as in the previous attempt
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
import { Maybe, Just, Nothing } from "./Maybe"; | |
import { Either, Left, Right } from "./Either"; | |
import { match } from "./match"; | |
const a: Maybe<number> = Just(5); | |
const b: Maybe<number> = Nothing(); | |
const x: Either<Error, number> = Right(10); | |
const y: Either<Error, string> = Left(new Error("DB broken bud")); | |
// match on a Maybe | |
// m has the inferred type number | null | |
let m = match(a, { | |
just: v => v, | |
nothing: () => null | |
}); | |
// n has the inferred type number | string | |
let n = match(b, { | |
just: v => v, | |
nothing: () => "ugh" | |
}); | |
// match on an Either | |
// o has the inferred type void | number | |
let o = match(x, { | |
left: err => console.log(err), | |
right: v => v | |
}); | |
// p has the inferred type string | { name: string } | |
let p = match(y, { | |
left: err => err.message, | |
right: v => ({ name: v }) | |
}); | |
console.log(m, n, o, p); |
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
// Either monad using discriminated unions | |
export type Either<L, R> = | |
| { type: "left"; value: L } | |
| { type: "right"; value: R }; | |
export function Left<L, R>(a: L): Either<L, R> { | |
return { | |
type: "left", | |
value: a | |
}; | |
} | |
export function Right<L, R>(b: R): Either<L, R> { | |
return { | |
type: "right", | |
value: b | |
}; | |
} | |
export type EitherMatchers<L, R, U, V> = { | |
left: (v: L) => U; | |
right: (v: R) => V; | |
}; |
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
// match/caseOf on Maybe and Either types | |
import { Maybe, MaybeMatchers } from "./Maybe"; | |
import { Either, EitherMatchers } from "./Either"; | |
export function match<T, U, V>( | |
v: Maybe<T>, | |
matchers: MaybeMatchers<T, U, V> | |
): U | V; | |
export function match<L, R, U, V>( | |
v: Either<L, R>, | |
matchers: EitherMatchers<L, R, U, V> | |
): U | V; | |
export function match(v: any, matchers: any) { | |
if (v.type === "left") { | |
return matchers.left(v.value); | |
} else if (v.type === "right") { | |
return matchers.right(v.value); | |
} else if (v.type === "just") { | |
return matchers.just(v.value); | |
} else if (v.type === "nothing") { | |
return matchers.nothing(); | |
} | |
} |
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
// Maybe monad using discriminated unions | |
export type Maybe<T> = { type: "just"; value: T } | { type: "nothing" }; | |
export function Just<T>(a: T): Maybe<T> { | |
return { | |
type: "just", | |
value: a | |
}; | |
} | |
export function Nothing<T>(): Maybe<T> { | |
return { | |
type: "nothing" | |
}; | |
} | |
export type MaybeMatchers<T, U, V> = { | |
just: (v: T) => U; | |
nothing: () => V; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment