Skip to content

Instantly share code, notes, and snippets.

@effe-megna
Last active February 3, 2020 21:37
Show Gist options
  • Select an option

  • Save effe-megna/0924b811a3c526eddf92f96d63e827fb to your computer and use it in GitHub Desktop.

Select an option

Save effe-megna/0924b811a3c526eddf92f96d63e827fb to your computer and use it in GitHub Desktop.
Try DataType for typescript, encoded as a class for Fluent API usage. (unsafe by spec :trollface:)
type TryADT <E, A> =
| { readonly _tag: "success", readonly success: A }
| { readonly _tag: "failure", readonly failure: E }
const success = <E, A>(successValue: A): TryADT<E, A> => ({ _tag: "success", success: successValue })
const failure = <E, A>(failureValue: E): TryADT<E, A> => ({ _tag: "failure", failure: failureValue })
class Try<E = never, A = never> {
internalValue!: TryADT<E, A>
private constructor(
value: TryADT<E, A>
) {
this.internalValue = value
}
static of = <E, A>(
computation: () => A,
onError: (reason: any) => E
): Try<E, A> => {
try {
const result = computation()
return new Try(success(result))
} catch (reason) {
return new Try(failure(onError(reason)))
}
}
getOrDefault = (def: A): A => {
return this.fold(
_ => def,
successValue => successValue
)
}
fold = <B>(onFailure: (failure: E) => B, onSuccess: (a: A) => B): B => {
if (this.internalValue._tag === "failure") {
return onFailure(this.internalValue.failure)
} else {
return onSuccess(this.internalValue.success)
}
}
map = <B>(f: (successValue: A) => B): Try<E, B> => {
const adt = this.fold(
failureValue => failure<E, B>(failureValue),
successValue => success(f(successValue))
)
return new Try(adt)
}
orNull = (): A | null => {
if (this.internalValue._tag === "failure") {
return null
} else {
return this.internalValue.success
}
}
recover = (recoveValue: A) => {
const adt = this.fold(
_ => success(recoveValue),
successValue => success(successValue)
)
return new Try(adt)
}
recoverWith = (tryableComputation: (failureValue: E) => Try<E, A>): Try<E, A> => {
return this.fold(
failureValue => tryableComputation(failureValue),
successValue => this.map(_ => successValue)
)
}
unsafeRaiseFailure = () => {
this.fold(
failure => { throw failure },
_ => { throw new Error("unsafeRaiseFailure called without failure inside") }
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment