Skip to content

Commit 8e4f870

Browse files
committed
chore: begin porting modules
1 parent 6b32858 commit 8e4f870

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1540
-2
lines changed

.changeset/weak-berries-fold.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@tsplus/stdlib": patch
3+
---
4+
5+
Port Option, List, ListBuffer, Equivalence, Ord, Utilities, Tuple, Function, Predicate

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ yarn-error.log
1111
.DS_Store
1212
compiler/
1313
dist/
14-
tmp/
14+
tmp/
15+
core/

src/collections/List.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
// codegen:start {preset: barrel, include: ./List/*.ts}
2+
export * from "./List/builder.js"
3+
export * from "./List/concat.js"
24
export * from "./List/definition.js"
5+
export * from "./List/empty.js"
6+
export * from "./List/exists.js"
7+
export * from "./List/filter.js"
8+
export * from "./List/find.js"
9+
export * from "./List/flatMap.js"
10+
export * from "./List/prependAll.js"
311
export * from "./List/reduce.js"
12+
export * from "./List/unsafeHead.js"
413
export * from "./List/unsafeTail.js"
514
// codegen:end

src/collections/List/builder.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ListBuffer } from "../mutable/ListBuffer.js"
2+
3+
export class ListBuilder<A> {
4+
constructor(private buffer: ListBuffer<A>) {}
5+
6+
append(a: A): ListBuilder<A> {
7+
this.buffer.append(a)
8+
return this
9+
}
10+
11+
build() {
12+
return this.buffer.toList
13+
}
14+
}
15+
16+
/**
17+
* @tsplus static ListOps builder
18+
*/
19+
export function builder<A>(): ListBuilder<A> {
20+
return new ListBuilder(new ListBuffer())
21+
}

src/collections/List/concat.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { List } from "./definition.js"
2+
3+
/**
4+
* @tsplus fluent List concat
5+
* @tsplus operator List &
6+
*/
7+
export function concat<A, B>(self: List<A>, that: List<B>): List<A | B> {
8+
return that.prependAll(self)
9+
}

src/collections/List/empty.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { List } from "./definition.js"
2+
3+
/**
4+
* Returns the empty `List`
5+
*
6+
* @tsplus static ListOps empty
7+
*/
8+
export function empty<A>(): List<A> {
9+
return List.nil()
10+
}

src/collections/List/exists.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { Predicate } from "../../data/Predicate.js"
2+
import type { List } from "./definition.js"
3+
4+
/**
5+
* @tsplus fluent List exists
6+
*/
7+
export function exists<A>(self: List<A>, p: Predicate<A>): boolean {
8+
let these = self
9+
while (!these.isNil()) {
10+
if (p(these.head)) {
11+
return true
12+
}
13+
these = these.tail
14+
}
15+
return false
16+
}

src/collections/List/filter.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/* eslint-disable no-constant-condition */
2+
import { unsafeCoerce } from "../../data/Function.js"
3+
import type { Predicate } from "../../data/Predicate.js"
4+
import { List } from "./definition.js"
5+
6+
/**
7+
* @tsplus fluent List filter
8+
*/
9+
export function filter<A>(self: List<A>, p: Predicate<A>): List<A> {
10+
return filterCommon_(self, p, false)
11+
}
12+
13+
function noneIn<A>(l: List<A>, p: Predicate<A>, isFlipped: boolean): List<A> {
14+
while (true) {
15+
if (l.isNil()) {
16+
return List.nil()
17+
} else {
18+
if (p(l.head) !== isFlipped) {
19+
return allIn(l, l.tail, p, isFlipped)
20+
} else {
21+
l = l.tail
22+
}
23+
}
24+
}
25+
}
26+
27+
function allIn<A>(
28+
start: List<A>,
29+
remaining: List<A>,
30+
p: Predicate<A>,
31+
isFlipped: boolean
32+
): List<A> {
33+
while (true) {
34+
if (remaining.isNil()) {
35+
return start
36+
} else {
37+
if (p(remaining.head) !== isFlipped) {
38+
remaining = remaining.tail
39+
} else {
40+
return partialFill(start, remaining, p, isFlipped)
41+
}
42+
}
43+
}
44+
}
45+
46+
function partialFill<A>(
47+
origStart: List<A>,
48+
firstMiss: List<A>,
49+
p: Predicate<A>,
50+
isFlipped: boolean
51+
): List<A> {
52+
const newHead = List.cons<A>(origStart.unsafeHead()!, List.nil())
53+
let toProcess = origStart.unsafeTail()! as List.Cons<A>
54+
let currentLast = newHead
55+
56+
while (!(toProcess === firstMiss)) {
57+
const newElem = List.cons(toProcess.unsafeHead()!, List.nil())
58+
currentLast.tail = newElem
59+
currentLast = unsafeCoerce(newElem)
60+
toProcess = unsafeCoerce(toProcess.tail)
61+
}
62+
63+
let next = firstMiss.tail
64+
let nextToCopy: List.Cons<A> = unsafeCoerce(next)
65+
while (!next.isNil()) {
66+
const head = next.unsafeHead()!
67+
if (p(head) !== isFlipped) {
68+
next = next.tail
69+
} else {
70+
while (!(nextToCopy === next)) {
71+
const newElem = List.cons(nextToCopy.unsafeHead()!, List.nil())
72+
currentLast.tail = newElem
73+
currentLast = newElem
74+
nextToCopy = unsafeCoerce(nextToCopy.tail)
75+
}
76+
nextToCopy = unsafeCoerce(next.tail)
77+
next = next.tail
78+
}
79+
}
80+
81+
if (!nextToCopy.isNil()) {
82+
currentLast.tail = nextToCopy
83+
}
84+
85+
return newHead
86+
}
87+
88+
function filterCommon_<A>(list: List<A>, p: Predicate<A>, isFlipped: boolean): List<A> {
89+
return noneIn(list, p, isFlipped)
90+
}

src/collections/List/find.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Option } from "../../data/Option.js"
2+
import type { Predicate } from "../../data/Predicate.js"
3+
import type { List } from "./definition.js"
4+
5+
/**
6+
* @tsplus fluent List find
7+
*/
8+
export function find<A>(self: List<A>, p: Predicate<A>): Option<A> {
9+
let these = self
10+
while (!these.isNil()) {
11+
if (p(these.head)) {
12+
return Option.some(these.head)
13+
}
14+
these = these.tail
15+
}
16+
return Option.none
17+
}

src/collections/List/flatMap.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { List } from "./definition.js"
2+
3+
/**
4+
* @tsplus fluent List flatMap
5+
*/
6+
export function flatMap<A, B>(self: List<A>, f: (a: A) => List<B>): List<B> {
7+
let rest = self
8+
let h: List.Cons<B> | undefined = undefined
9+
let t: List.Cons<B> | undefined = undefined
10+
while (!rest.isNil()) {
11+
let bs = f(rest.head)
12+
while (!bs.isNil()) {
13+
const nx = List.cons(bs.head, List.nil())
14+
if (t === undefined) {
15+
h = nx
16+
} else {
17+
t.tail = nx
18+
}
19+
t = nx
20+
bs = bs.tail
21+
}
22+
rest = rest.tail
23+
}
24+
if (h === undefined) return List.nil()
25+
else return h
26+
}

0 commit comments

Comments
 (0)