diff --git a/src/algebra/io.js b/src/algebra/io.js new file mode 100644 index 0000000..a5e0782 --- /dev/null +++ b/src/algebra/io.js @@ -0,0 +1,53 @@ +import { Algebra, Monad } from './index.js' + +/** @import { Fn, InferredMorphism, Morphism } from './types.js' */ + +/** @template {Fn} T */ +export class IO extends Algebra(Monad) { + _effect + + /** + * @type {T} effect + */ + constructor(effect) { + super() + this._effect = effect + } + + /** + * @template {Fn} T + * @param {T} a + */ + static of(a) { + return new IO(() => a) + } + + /** + * @param {InferredMorphism} f + */ + chain(f) { + return IO.of(() => f(this.run()).run()) + } + + /** + * @param {InferredMorphism} f + */ + map(f) { + return IO.of(() => f(this.run())) + } + + /** + * @template {Fn} U + * @this {IO} + * @param {IO>} other + * @returns {IO} + */ + ap(other) { + return IO.of(() => other.run()(this.run())) + } + + run() { + return this._effect() + } +} + diff --git a/src/algebra/list.js b/src/algebra/list.js index 171cbd7..bc84dae 100644 --- a/src/algebra/list.js +++ b/src/algebra/list.js @@ -1,7 +1,7 @@ import { Pure, Suspend } from './free.js' import { AlgebraWithBase, Category, Comonad, Foldable, Monoid } from './index.js' -/** @import { InferredMorphism } from './types.js' */ +/** @import { InferredMorphism, Morphism } from './types.js' */ const Nil = Symbol('Nil') @@ -26,6 +26,27 @@ class ListPure extends AlgebraWithBase(Pure)(Category, Foldable, Monoid) { return Empty } + /** + * @template U + * @this {ListPure} + * @param {Morphism>} f + * @returns {ListPure} + */ + chain(f) { + return f(this.head()) + } + + /** + * @template U + * @this {ListPure} + * @param {Morphism} f + * @returns {ListPure} + */ + map(f) { + return new ListPure(f(this._value)) + } + + /** * @template U * @param {(acc: U, value: T) => U} f