add reader
This commit is contained in:
parent
6e2f725e7a
commit
1fec16c29c
5 changed files with 120 additions and 18 deletions
|
@ -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() {
|
||||
|
|
|
@ -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), []))
|
||||
|
||||
|
|
|
@ -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
71
src/algebra/reader.js
Normal 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ export class Ok extends Algebra(Monad, Foldable) {
|
|||
*/
|
||||
constructor(value) {
|
||||
super()
|
||||
|
||||
this.#value = value
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue