Skip to content

Instantly share code, notes, and snippets.

@alarbada
Last active March 23, 2021 11:44
Show Gist options
  • Save alarbada/06f86d7840f68a0570fdadc7e8d9c9e8 to your computer and use it in GitHub Desktop.
Save alarbada/06f86d7840f68a0570fdadc7e8d9c9e8 to your computer and use it in GitHub Desktop.
Typescript with F# computation expressions experiment
// Extended from https://apoberejnyi.medium.com/do-notation-for-either-in-typescript-c207e5987b7a
// Library
type Option<T> = T | null
class OptionError extends Error {
constructor() {
super()
}
}
const runOption = <T>(value: Option<T>): T => {
if (value === null) {
throw new OptionError()
}
return value
}
function doOption<T>(
callback: (runner: <Q>(option: Option<Q>) => Q) => Option<T>
): Option<T> {
try {
const result = callback(runOption)
return result
} catch (error) {
if (error instanceof OptionError) {
return null
}
throw error
}
}
// Examples
class Positive {
constructor(public val: number, private _?: string) {}
}
class Negative {
constructor(public val: number, private _?: string) {}
}
const createPositive = (n: number): Option<Positive> => {
if (n > 0) {
return new Positive(n)
}
return null
}
const createNegative = (n: number): Option<Negative> => {
if (n <= 0) {
return new Negative(n)
}
return null
}
const multiplyPositives = (n1: Positive, n2: Positive) => {
return new Positive(n1.val * n2.val)
}
const main = async () => {
const result = await doOption(async (run) => {
const p1 = run(createPositive(3))
const p2 = run(createNegative(2))
return { p1, p2 }
})
console.log('result', result)
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment