finished list

This commit is contained in:
Rowan 2025-04-06 15:52:57 -05:00
parent 0336213ca9
commit 6e2f725e7a
3 changed files with 64 additions and 13 deletions

View file

@ -1,5 +1,5 @@
import { curry } from '../curry.js' import { curry } from '../curry.js'
import { Free, Suspend, suspend, pure } from './free.js' import { Suspend, suspend, pure } from './free.js'
/** @import {InferredMorphism, Morphism, ChainConstructor} from './types.js' */ /** @import {InferredMorphism, Morphism, ChainConstructor} from './types.js' */
@ -42,4 +42,3 @@ export const liftF = x => suspend(
/** @type {InferredMorphism<T>} */(pure) /** @type {InferredMorphism<T>} */(pure)
) )

View file

@ -1,3 +1,4 @@
import { concat } from '../iter.js'
import { liftF } from './fn.js' import { liftF } from './fn.js'
import { Pure, Suspend } from './free.js' import { Pure, Suspend } from './free.js'
import { AlgebraWithBase, Comonad, Foldable } from './index.js' import { AlgebraWithBase, Comonad, Foldable } from './index.js'
@ -12,7 +13,7 @@ const Nil = Symbol('Nil')
*/ */
class ListPure extends AlgebraWithBase(Pure)(Foldable) { class ListPure extends AlgebraWithBase(Pure)(Foldable) {
head() { head() {
return this.head return this._value
} }
tail() { tail() {
@ -21,8 +22,8 @@ class ListPure extends AlgebraWithBase(Pure)(Foldable) {
/** /**
* @template U * @template U
* @param {(acc: U, value: T) => U} f * @param {(acc: U, value: T) => U} f
* @param {U} init * @param {U} init
* @returns {U} * @returns {U}
*/ */
reduce(f, init) { reduce(f, init) {
@ -30,14 +31,13 @@ class ListPure extends AlgebraWithBase(Pure)(Foldable) {
} }
} }
/** /**
* @template T * @template T
* @extends {Suspend<T>} * @extends {Suspend<T>}
*/ */
class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Comonad) { class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Comonad) {
/** /**
* @param {IteratorObject<T>} iter * @param {Iterator<T>} iter
*/ */
constructor(iter) { constructor(iter) {
const next = iter.next() const next = iter.next()
@ -47,6 +47,16 @@ class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Comonad) {
super(value, fn) super(value, fn)
} }
/**
* @template {Iterable<T>} T
* @this {ListSuspend<Iterator<T>>}
* @param {Iterator<T>} value
* @returns {ListSuspend<T>}
*/
cons(value) {
return new ListSuspend(concat(value, this._value))
}
head() { head() {
return this._value return this._value
} }
@ -57,8 +67,8 @@ class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Comonad) {
/** /**
* @template U * @template U
* @param {(acc: U, value: T) => U} f * @param {(acc: U, value: T) => U} f
* @param {U} init * @param {U} init
* @returns {U} * @returns {U}
*/ */
reduce(f, init) { reduce(f, init) {
@ -67,7 +77,7 @@ class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Comonad) {
} }
extract() { extract() {
return this.reduce((acc, value) => acc.concat(value), []) return this.reduce(reduceArray, [])
} }
} }
@ -78,7 +88,7 @@ class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Comonad) {
export class List { export class List {
/** /**
* @template {Iterable<T>} T * @template {Iterable<T>} T
* @param {T} value * @param {T} value
* @returns {ListSuspend<T>} * @returns {ListSuspend<T>}
*/ */
static of(value) { static of(value) {
@ -88,7 +98,7 @@ export class List {
/** /**
* @template T * @template T
* @param {Iterable<T>} iterator * @param {Iterable<T>} iterator
* @returns {ListSuspend<T>} * @returns {ListSuspend<T>}
*/ */
static from(iterator) { static from(iterator) {
@ -102,8 +112,16 @@ export class List {
const Empty = new ListPure(Nil) const Empty = new ListPure(Nil)
/**
* @template T
* @param {T[]} acc
* @param {T} value
* @returns {T[]}
*/
const reduceArray = (acc, value) => acc.concat(value)
const a = Array.from({ length: 100 }).map((_, i) => i)
const a = Array.from({ length: 10 }).map((_, i) => i)
const wawa = List.from(a) const wawa = List.from(a)
console.log(wawa.reduce((acc, value) => acc.concat(value), [])) console.log(wawa.reduce((acc, value) => acc.concat(value), []))

34
src/iter.js Normal file
View file

@ -0,0 +1,34 @@
/**
* @template T
* @param {T | Iterable<T> | Iterator<T>} value
* @returns {value is Iterable<T>}
*/
export function isIterable(value) {
return value[Symbol.iterator] != null
}
/**
* @template T
* @param {T | Iterable<T> | Iterator<T>} value
* @yields {T}
*/
export function* iter(value) {
if (isIterable(value)) {
yield* Iterator.from(value)
} else {
yield value
}
}
/**
* @template T
* @param {...(Iterable<T> | Iterator<T>)} iterators
* @yields {T}
*/
export const concat = function*(...iterators) {
for (const iter of iterators) {
for (const item of Iterator.from(iter)) {
yield item
}
}
}