Add Do notation for option
This commit is contained in:
parent
52e00c3f38
commit
75368c8ef8
@ -10,9 +10,8 @@ export const some = <A>(value: A): Option<A> => ({
|
||||
})
|
||||
|
||||
// Operations
|
||||
export const map =
|
||||
<A, B>(f: (a: A) => B) => (fa: Option<A>): Option<B> =>
|
||||
fa._tag === 'Some' ? some(f(fa.value)) : none
|
||||
export const map = <A, B>(f: (a: A) => B) => (fa: Option<A>): Option<B> =>
|
||||
fa._tag === 'Some' ? some(f(fa.value)) : none
|
||||
|
||||
export const chain =
|
||||
<A, B>(f: (a: A) => Option<B>) => (fa: Option<A>): Option<B> =>
|
||||
@ -20,3 +19,37 @@ export const chain =
|
||||
|
||||
export const getOrElse = <A>(defaultValue: A) => (fa: Option<A>): A =>
|
||||
fa._tag === 'Some' ? fa.value : defaultValue
|
||||
|
||||
export class DoOption<T extends Record<string, unknown>> {
|
||||
constructor(private readonly option: Option<T>) {}
|
||||
|
||||
bind<K extends string, A>(key: K, fa: Option<A>): DoOption<T & Record<K, A>> {
|
||||
const newOption = chain((scope: T) =>
|
||||
map((a: A) => ({...scope, [key]: a}))(fa)
|
||||
)(this.option)
|
||||
return new DoOption(newOption as Option<T & Record<K, A>>)
|
||||
}
|
||||
|
||||
return<B>(f: (scope: T) => B): Option<B> {
|
||||
return map(f)(this.option)
|
||||
}
|
||||
|
||||
done(): Option<T> {
|
||||
return this.option
|
||||
}
|
||||
do(fa: Option<unknown>): DoOption<T> {
|
||||
const newOption = chain((scope: T) => map(() => scope)(fa))(this.option)
|
||||
return new DoOption(newOption)
|
||||
}
|
||||
|
||||
doL(f: (scope: T) => Option<unknown>): DoOption<T> {
|
||||
const newOption = chain((scope: T) => map(() => scope)(f(scope)))(
|
||||
this.option,
|
||||
)
|
||||
return new DoOption(newOption)
|
||||
}
|
||||
|
||||
static start(): DoOption<{}> {
|
||||
return new DoOption(some({}))
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user