This commit is contained in:
themodernhakr 2025-06-02 23:12:26 -05:00
parent 0d3bf40b59
commit b2d1a6e958

View File

@ -1,36 +1,43 @@
export type Nil = { readonly _tag: 'Nil' }; export type Nil = {readonly _tag: 'Nil'}
export type Cons<A> = { export type Cons<A> = {
readonly _tag: 'Cons'; readonly _tag: 'Cons',
readonly head: A; readonly head: A,
readonly tail: List<A>; readonly tail: List<A>,
}; }
export type List<A> = Nil | Cons<A>; export type List<A> = Nil | Cons<A>
// Constructors // Constructors
export const nil: Nil = { _tag: 'Nil' }; export const nil: Nil = {_tag: 'Nil'}
export const cons = <A>(head: A, tail: List<A>): List<A> => ({ export const cons = <A>(head: A, tail: List<A>): List<A> => ({
_tag: 'Cons', _tag: 'Cons',
head, head,
tail, tail,
}); })
// Operations // Operations
type ListMap = <A, B>(f: (a: A) => B) => (fa: List<A>) => List<B>; type ListMap = <A, B>(f: (a: A) => B) => (fa: List<A>) => List<B>
export const listMap: ListMap = (f) => (fa) => export const listMap: ListMap = f => fa =>
fa._tag === 'Cons' ? cons(f(fa.head), listMap(f)(fa.tail)) : nil; fa._tag === 'Cons' ? cons(f(fa.head), listMap(f)(fa.tail)) : nil
type ListReduce = <A, B>( type ListReduce = <A, B>(
f: (b: B, a: A) => B, f: (b: B, a: A) => B,
initial: B initial: B,
) => (fa: List<A>) => B; ) => (fa: List<A>) => B
export const listReduce: ListReduce = (f, initial) => (fa) => export const listReduce: ListReduce = (f, initial) => fa =>
fa._tag === 'Cons' ? listReduce(f, f(initial, fa.head))(fa.tail) : initial; fa._tag === 'Cons' ? listReduce(f, f(initial, fa.head))(fa.tail)
: initial
// Helpers // Helpers
type FromArray = <A>(arr: Array<A>) => List<A>; type FromArray = <A>(arr: Array<A>) => List<A>
export const fromArray: FromArray = <A>(arr: Array<A>) => export const fromArray: FromArray = <A>(arr: Array<A>) =>
arr.reduceRight((acc: List<A>, val: A) => cons(val, acc), nil as List<A>); arr.reduceRight(
(acc: List<A>, val: A) => cons(val, acc),
nil as List<A>,
)
type ToArray = <A>(fa: List<A>) => Array<A>; type ToArray = <A>(fa: List<A>) => Array<A>
export const toArray: ToArray = <A>(fa: List<A>) => export const toArray: ToArray = <A>(fa: List<A>) =>
listReduce<A, Array<A>>((acc, val) => [...acc, val], [] as Array<A>)(fa); listReduce<A, Array<A>>(
(acc, val) => [...acc, val],
[] as Array<A>,
)(fa)