List.count
This commit is contained in:
parent
b2d5ece8f0
commit
50f3cff3d9
2 changed files with 64 additions and 22 deletions
|
@ -42,3 +42,10 @@ export const liftF = x => suspend(
|
|||
/** @type {InferredMorphism<T>} */(pure)
|
||||
)
|
||||
|
||||
/**
|
||||
* @param {number} a
|
||||
* @param {number} b
|
||||
* @returns {number}
|
||||
*/
|
||||
export const sum = (a, b) => a + b
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { concat } from '../iter.js'
|
||||
import { liftF } from './fn.js'
|
||||
import { Pure, Suspend } from './free.js'
|
||||
import { AlgebraWithBase, Category, Comonad, Foldable, Monoid } from './index.js'
|
||||
|
||||
|
@ -37,6 +35,18 @@ class ListPure extends AlgebraWithBase(Pure)(Category, Foldable, Monoid) {
|
|||
reduce(f, init) {
|
||||
return f(init, this._value)
|
||||
}
|
||||
|
||||
count() {
|
||||
return this.isEmpty() ? 0 : 1
|
||||
}
|
||||
|
||||
/**
|
||||
* @this {List<any>}
|
||||
* @returns {this is Empty}
|
||||
*/
|
||||
isEmpty() {
|
||||
return this === Empty
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,24 +55,29 @@ class ListPure extends AlgebraWithBase(Pure)(Category, Foldable, Monoid) {
|
|||
*/
|
||||
class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Monoid, Comonad) {
|
||||
/**
|
||||
* @param {Iterator<T>} iter
|
||||
* @param {T} head
|
||||
* @param {() => List<T>} tail
|
||||
*/
|
||||
constructor(iter) {
|
||||
const next = iter.next()
|
||||
const value = /** @type {T} */ (next.value)
|
||||
constructor(head, tail) {
|
||||
super(
|
||||
head,
|
||||
/** @type {InferredMorphism<T>} */(tail)
|
||||
)
|
||||
}
|
||||
|
||||
const fn = /** @type {InferredMorphism<T>} */ (next.done ? List.empty : () => new ListSuspend(iter))
|
||||
super(value, fn)
|
||||
|
||||
static empty() {
|
||||
return List.empty()
|
||||
}
|
||||
|
||||
/**
|
||||
* @template {Iterable<T>} T
|
||||
* @this {ListSuspend<Iterator<T>>}
|
||||
* @param {Iterator<T>} value
|
||||
* @template T
|
||||
* @this {ListSuspend<T>}
|
||||
* @param {T} value
|
||||
* @returns {ListSuspend<T>}
|
||||
*/
|
||||
cons(value) {
|
||||
return new ListSuspend(concat(value, this._value))
|
||||
return new ListSuspend(value, () => this)
|
||||
}
|
||||
|
||||
head() {
|
||||
|
@ -88,8 +103,13 @@ class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Monoid, Comonad) {
|
|||
return this.reduce(reduceArray, [])
|
||||
}
|
||||
|
||||
static empty() {
|
||||
return List.empty()
|
||||
count() {
|
||||
return this.tail().count() + 1
|
||||
}
|
||||
|
||||
/** @returns {this is Empty} */
|
||||
isEmpty() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,22 +119,37 @@ class ListSuspend extends AlgebraWithBase(Suspend)(Foldable, Monoid, Comonad) {
|
|||
*/
|
||||
export class List {
|
||||
/**
|
||||
* @template {Iterable<T>} T
|
||||
* @template T
|
||||
* @param {T} value
|
||||
* @returns {ListSuspend<T>}
|
||||
* @returns {List<T>}
|
||||
*/
|
||||
static of(value) {
|
||||
// @ts-ignore
|
||||
return new ListSuspend(liftF(value))
|
||||
return new ListSuspend(value, List.empty)
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {Iterable<T>} iterator
|
||||
* @returns {ListSuspend<T>}
|
||||
* @param {Iterable<T>} iterable
|
||||
* @returns {List<T>}
|
||||
*/
|
||||
static from(iterator) {
|
||||
return new ListSuspend(Iterator.from(iterator))
|
||||
static from(iterable) {
|
||||
const iterator = Iterator.from(iterable)
|
||||
return List.fromIterator(iterator)
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {Iterator<T>} iterator
|
||||
* @returns {List<T>}
|
||||
*/
|
||||
static fromIterator(iterator) {
|
||||
const next = iterator.next()
|
||||
|
||||
if (next.done) {
|
||||
return List.empty()
|
||||
} else {
|
||||
return new ListSuspend(next.value, () => List.fromIterator(iterator))
|
||||
}
|
||||
}
|
||||
|
||||
static empty() {
|
||||
|
|
Loading…
Add table
Reference in a new issue