diff --git a/exercises/practice/list-ops/.meta/proof.ci.ts b/exercises/practice/list-ops/.meta/proof.ci.ts index 34b8f5897..1c5b6bf1a 100644 --- a/exercises/practice/list-ops/.meta/proof.ci.ts +++ b/exercises/practice/list-ops/.meta/proof.ci.ts @@ -1,4 +1,4 @@ -const Null: Cons = { +const Null: Cons = { get value() { return undefined }, @@ -10,17 +10,17 @@ const Null: Cons = { return this.value }, - push(item): Cons { + push(item: T): Cons { // eslint-disable-next-line @typescript-eslint/no-use-before-define - return new Cons(item, this) + return new Cons(item, this) as Cons }, length() { return 0 }, - append(other: Cons): Cons { + append(other: Cons): Cons { return other }, - concat(): Cons { + concat(): Cons { return this }, forEach(): void { @@ -38,27 +38,27 @@ const Null: Cons = { ): TReturn { return initial as TReturn }, - filter(): Cons { + filter(): Cons { return Null }, - reverse(): Cons { + reverse(): Cons { return this }, - map(): Cons { - return this + map(): Cons { + return this as Cons }, } -class Cons { +class Cons { constructor( - public readonly value: unknown, - public next: Cons = Null + public readonly value: T, + public next: Cons = Null as Cons ) {} - public get(i: number): unknown { + public get(i: number): T | undefined { return i === 0 ? this.value : this.next.get(i - 1) } - public push(item: unknown): this { + public push(item: T): this { this.next = this.next.push(item) return this } @@ -67,83 +67,78 @@ class Cons { return 1 + this.next.length() } - public append(other: Cons): Cons { + public append(other: Cons): Cons { return other.foldl((result, item) => result.push(item), this) } - public concat(others: Cons): Cons { - return others.foldl( - (result, other) => result.append(other), - this - ) + public concat(others: Cons>): Cons { + return others.foldl>((result, other) => result.append(other), this) } - public foldl( - callback: (initial: TValue, value: TValue) => TValue - ): TValue - public foldl( - callback: (initial: TReturn, value: TValue) => TReturn, + public foldl( + callback: (initial: TReturn, value: T) => TReturn + ): TReturn + public foldl( + callback: (initial: TReturn, value: T) => TReturn, initial: TReturn ): TReturn - - public foldl( - callback: (initial: TReturn | undefined, value: TValue) => TReturn, + public foldl( + callback: (initial: TReturn | undefined, value: T) => TReturn, initial?: TReturn ): TReturn { - return this.next.foldl( - callback, - callback(initial, this.value as TValue) - ) + return this.next.foldl(callback, callback(initial, this.value)) } - public forEach(callback: (value: unknown) => void): void { + public forEach(callback: (value: T) => void): void { this.foldl((_, item) => callback(item)) } - public foldr( - callback: (initial: TValue, value: TValue) => TValue - ): TValue - public foldr( - callback: (initial: TReturn, value: TValue) => TReturn, + public foldr( + callback: (initial: TReturn, value: T) => TReturn + ): TReturn + public foldr( + callback: (initial: TReturn, value: T) => TReturn, initial: TReturn ): TReturn - - public foldr( - callback: (initial: TReturn, value: TValue) => TReturn, + public foldr( + callback: (initial: TReturn, value: T) => TReturn, initial?: TReturn ): TReturn { return callback( - this.next.foldr(callback, initial as TReturn), - this.value as TValue + this.next.foldr( + callback as (initial: TReturn, value: T | undefined) => TReturn, + initial as TReturn + ), + this.value ) } - public filter(predicate: (value: TValue) => boolean): Cons { - return this.foldl( + public filter(predicate: (value: T) => boolean): Cons { + return this.foldl>( (result, item) => (predicate(item) && result.push(item)) || result, - Null + Null as Cons ) } - public map( - expression: (value: TValue) => TReturn - ): Cons { - return this.foldl( + public map( + expression: (value: T) => TReturn + ): Cons { + return this.foldl( (result, item) => result.push(expression(item)), - Null + Null as Cons ) } - public reverse(): Cons { + public reverse(): Cons { return this.next.reverse().push(this.value) } } export class List { - public static create(...values: unknown[]): Cons { + public static create(...values: T[]): Cons { const [head, ...tail] = values if (head === undefined) { - return Null + return Null as Cons } return new Cons(head, List.create(...tail)) diff --git a/exercises/practice/list-ops/list-ops.test.ts b/exercises/practice/list-ops/list-ops.test.ts index 484198e7a..73564b309 100644 --- a/exercises/practice/list-ops/list-ops.test.ts +++ b/exercises/practice/list-ops/list-ops.test.ts @@ -66,14 +66,14 @@ describe('append entries to a list and return the new list', () => { }) xit('list to empty list', () => { - const list1 = List.create() + const list1 = List.create() const list2 = List.create(1, 2, 3, 4) expect(list1.append(list2)).toEqual(list2) }) xit('empty list to list', () => { const list1 = List.create(1, 2, 3, 4) - const list2 = List.create() + const list2 = List.create() expect(list1.append(list2)).toEqual(list1) }) @@ -87,14 +87,14 @@ describe('append entries to a list and return the new list', () => { describe('concat lists and lists of lists into new list', () => { xit('empty list', () => { const list1 = List.create() - const list2 = List.create() + const list2 = List.create>() expect(list1.concat(list2)).toHaveValues() }) xit('list of lists', () => { const list1 = List.create(1, 2) const list2 = List.create(3) - const list3 = List.create() + const list3 = List.create() const list4 = List.create(4, 5, 6) const listOfLists = List.create(list2, list3, list4) expect(list1.concat(listOfLists)).toHaveValues(1, 2, 3, 4, 5, 6) @@ -103,13 +103,13 @@ describe('concat lists and lists of lists into new list', () => { describe('filter list returning only values that satisfy the filter function', () => { xit('empty list', () => { - const list1 = List.create() - expect(list1.filter((el) => el % 2 === 1)).toHaveValues() + const list1 = List.create() + expect(list1.filter((el) => el % 2 === 1)).toHaveValues() }) xit('non empty list', () => { const list1 = List.create(1, 2, 3, 5) - expect(list1.filter((el) => el % 2 === 1)).toHaveValues(1, 3, 5) + expect(list1.filter((el) => el % 2 === 1)).toHaveValues(1, 3, 5) }) }) @@ -127,47 +127,47 @@ describe('returns the length of a list', () => { describe('returns a list of elements whose values equal the list value transformed by the mapping function', () => { xit('empty list', () => { - const list1 = List.create() - expect(list1.map((el) => ++el)).toHaveValues() + const list1 = List.create() + expect(list1.map((el) => ++el)).toHaveValues() }) xit('non-empty list', () => { const list1 = List.create(1, 3, 5, 7) - expect(list1.map((el) => ++el)).toHaveValues(2, 4, 6, 8) + expect(list1.map((el) => ++el)).toHaveValues(2, 4, 6, 8) }) }) describe('folds (reduces) the given list from the left with a function', () => { xit('empty list', () => { - const list1 = List.create() - expect(list1.foldl((acc, el) => el * acc, 2)).toEqual(2) + const list1 = List.create() + expect(list1.foldl((acc, el) => el * acc, 2)).toEqual(2) }) xit('direction independent function applied to non-empty list', () => { const list1 = List.create(1, 2, 3, 4) - expect(list1.foldl((acc, el) => acc + el, 5)).toEqual(15) + expect(list1.foldl((acc, el) => acc + el, 5)).toEqual(15) }) xit('direction dependent function applied to non-empty list', () => { const list1 = List.create(1, 2, 3, 4) - expect(list1.foldl((acc, el) => el / acc, 24)).toEqual(64) + expect(list1.foldl((acc, el) => el / acc, 24)).toEqual(64) }) }) describe('folds (reduces) the given list from the right with a function', () => { xit('empty list', () => { - const list1 = List.create() - expect(list1.foldr((acc, el) => el * acc, 2)).toEqual(2) + const list1 = List.create() + expect(list1.foldr((acc, el) => el * acc, 2)).toEqual(2) }) xit('direction independent function applied to non-empty list', () => { const list1 = List.create(1, 2, 3, 4) - expect(list1.foldr((acc, el) => acc + el, 5)).toEqual(15) + expect(list1.foldr((acc, el) => acc + el, 5)).toEqual(15) }) xit('direction dependent function applied to non-empty list', () => { const list1 = List.create(1, 2, 3, 4) - expect(list1.foldr((acc, el) => el / acc, 24)).toEqual(9) + expect(list1.foldr((acc, el) => el / acc, 24)).toEqual(9) }) })