add reader

This commit is contained in:
Rowan 2025-04-06 18:23:53 -05:00
parent 6e2f725e7a
commit 1fec16c29c
5 changed files with 120 additions and 18 deletions

View file

@ -1,5 +1,5 @@
import { liftF } from './fn.js'
import { Algebra, BaseSet, Comonad, Monad } from './index.js'
import { Algebra, BaseSet, Monad, Semigroupoid } from './index.js'
/** @import { InferredMorphism, Morphism } from './types.js' */
@ -8,7 +8,7 @@ import { Algebra, BaseSet, Comonad, Monad } from './index.js'
* @extends BaseSet
* @mixes Monad
*/
export class Suspend extends Algebra(Monad) {
export class Suspend extends Algebra(Semigroupoid, Monad) {
_value
#fn
@ -55,6 +55,14 @@ export class Suspend extends Algebra(Monad) {
return this.map(g)
}
/**
* @template T
* @param {InferredMorphism<T>} other
*/
compose(other) {
return this.chain(() => other)
}
step() {
return this.#fn(this._value)
}
@ -65,7 +73,7 @@ export class Suspend extends Algebra(Monad) {
}
/** @template T */
export class Pure extends Algebra(Monad, Comonad) {
export class Pure extends Algebra(Monad) {
_value
/** @param {T} value */
@ -95,7 +103,7 @@ export class Pure extends Algebra(Monad, Comonad) {
* @returns {Pure<U>}
*/
map(f) {
return this.chain(x => new Pure(f(x)))
return this.chain(x => pure(f(x)))
}
/**
@ -107,8 +115,12 @@ export class Pure extends Algebra(Monad, Comonad) {
return this.map(f)
}
extract() {
return this._value
/**
* @template T
* @param {InferredMorphism<T>} other
*/
compose(other) {
return this.chain(() => pure(other))
}
step() {

View file

@ -1,7 +1,7 @@
import { concat } from '../iter.js'
import { liftF } from './fn.js'
import { Pure, Suspend } from './free.js'
import { AlgebraWithBase, Comonad, Foldable } from './index.js'
import { AlgebraWithBase, Category, Comonad, Foldable, Monoid } from './index.js'
/** @import { InferredMorphism } from './types.js' */
@ -11,7 +11,15 @@ const Nil = Symbol('Nil')
* @template T
* @extends {Pure<T>}
*/
class ListPure extends AlgebraWithBase(Pure)(Foldable) {
class ListPure extends AlgebraWithBase(Pure)(Category, Foldable, Monoid) {
static empty() {
return List.empty()
}
static id() {
return List.empty()
}
head() {
return this._value
}
@ -35,7 +43,7 @@ class ListPure extends AlgebraWithBase(Pure)(Foldable) {
* @template T
* @extends {Suspend<T>}
*/
class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Comonad) {
class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Monoid, Comonad) {
/**
* @param {Iterator<T>} iter
*/
@ -79,6 +87,10 @@ class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Comonad) {
extract() {
return this.reduce(reduceArray, [])
}
static empty() {
return List.empty()
}
}
/**
@ -120,9 +132,3 @@ const Empty = new ListPure(Nil)
*/
const reduceArray = (acc, value) => acc.concat(value)
const a = Array.from({ length: 10 }).map((_, i) => i)
const wawa = List.from(a)
console.log(wawa.reduce((acc, value) => acc.concat(value), []))

View file

@ -1,9 +1,9 @@
import { Algebra, Foldable, Functor, Monad } from './index.js'
import { Algebra, Foldable, Monad, Monoid } from './index.js'
/** @import { Morphism } from './types.js' */
/** @template T */
export class Some extends Algebra(Monad, Foldable) {
export class Some extends Algebra(Monoid, Monad, Foldable) {
/** @type {T} */
#value
@ -59,10 +59,14 @@ export class Some extends Algebra(Monad, Foldable) {
reduce(f, init) {
return f(init, this.#value)
}
empty() {
return Option.empty()
}
}
/** @template T */
class None extends Algebra(Monad, Foldable) {
class None extends Algebra(Monoid, Monad, Foldable) {
/**
* @template R
* @param {Morphism<T, R>} _f
@ -99,6 +103,10 @@ class None extends Algebra(Monad, Foldable) {
reduce(_f, init) {
return init
}
empty() {
return Option.empty()
}
}
/**
@ -113,6 +121,10 @@ export class Option {
static of(value) {
return Some.of(value)
}
static empty() {
return none
}
}
/**

71
src/algebra/reader.js Normal file
View file

@ -0,0 +1,71 @@
import { id } from './fn.js'
import { Algebra, Monad } from './index.js'
/** @import { InferredMorphism } from './types.js' */
/**
* @template T
* @typedef {InferredMorphism<T>} ReaderFn
*/
/** @template T */
export class Reader extends Algebra(Monad) {
#run
/**
* @param {InferredMorphism<T>} run
*/
constructor(run) {
super()
this.#run = run
}
/**
* @template T
* @param {T} a
* @returns {Reader<T>}
*/
static of(a) {
return new Reader(/** @type {InferredMorphism<T>} */(_env => a))
}
/** @template T */
static ask() {
return new Reader(/** @type {InferredMorphism<T>} */(id))
}
/**
* @param {InferredMorphism<T>} f
* @returns {Reader<T>}
*/
map(f) {
return new Reader(/** @type {InferredMorphism<T>} */(env => f(this.#run(env))))
}
/**
* @param {InferredMorphism<T>} f
* @returns {Reader<T>}
*/
chain(f) {
return new Reader(env => f(this.#run(env)).run(env))
}
/**
* @param {InferredMorphism<T>} f
* @returns {Reader<T>}
*/
local(f) {
return new Reader(/** @type {InferredMorphism<T>} */(env => this.#run(f(env))))
}
/**
* @template R
* @param {T} env
* @returns {R}
*/
run(env) {
return this.#run(env)
}
}

View file

@ -15,6 +15,7 @@ export class Ok extends Algebra(Monad, Foldable) {
*/
constructor(value) {
super()
this.#value = value
}