diff --git a/src/lib/util/basic/option.ts b/src/lib/util/basic/option.ts
index 165c0c1..a036e00 100644
--- a/src/lib/util/basic/option.ts
+++ b/src/lib/util/basic/option.ts
@@ -10,9 +10,8 @@ export const some = (value: A): Option => ({
})
// Operations
-export const map =
- (f: (a: A) => B) => (fa: Option): Option =>
- fa._tag === 'Some' ? some(f(fa.value)) : none
+export const map = (f: (a: A) => B) => (fa: Option): Option =>
+ fa._tag === 'Some' ? some(f(fa.value)) : none
export const chain =
(f: (a: A) => Option) => (fa: Option): Option =>
@@ -20,3 +19,37 @@ export const chain =
export const getOrElse = (defaultValue: A) => (fa: Option): A =>
fa._tag === 'Some' ? fa.value : defaultValue
+
+export class DoOption> {
+ constructor(private readonly option: Option) {}
+
+ bind(key: K, fa: Option): DoOption> {
+ const newOption = chain((scope: T) =>
+ map((a: A) => ({...scope, [key]: a}))(fa)
+ )(this.option)
+ return new DoOption(newOption as Option>)
+ }
+
+ return(f: (scope: T) => B): Option {
+ return map(f)(this.option)
+ }
+
+ done(): Option {
+ return this.option
+ }
+ do(fa: Option): DoOption {
+ const newOption = chain((scope: T) => map(() => scope)(fa))(this.option)
+ return new DoOption(newOption)
+ }
+
+ doL(f: (scope: T) => Option): DoOption {
+ const newOption = chain((scope: T) => map(() => scope)(f(scope)))(
+ this.option,
+ )
+ return new DoOption(newOption)
+ }
+
+ static start(): DoOption<{}> {
+ return new DoOption(some({}))
+ }
+}