-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #95 from poteat/poteat/more-reified-utilities
More reified utilities
- Loading branch information
Showing
35 changed files
with
1,160 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { $, Test, DigitList } from '..' | ||
|
||
type FromHex_Spec = [ | ||
/** | ||
* Can convert a list of hex digits to a list of decimal digits. | ||
*/ | ||
Test.Expect<$<DigitList.FromHex, [['7'], ['1', '1']]>, ['1', '2', '3']>, | ||
|
||
/** | ||
* Can convert a list of hex digits to a list of decimal digits. | ||
*/ | ||
Test.Expect<$<DigitList.FromHex, [['1', '1'], ['1', '1']]>, ['1', '8', '7']>, | ||
|
||
/** | ||
* Can convert zero. | ||
*/ | ||
Test.Expect<$<DigitList.FromHex, [['0']]>, ['0']> | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { Kind, Type, DigitList } from '..' | ||
|
||
/** | ||
* `_$fromHex` is a type-level function that takes in a list of hex digits | ||
* `T`, and returns a list of decimal digits. The hex digits are represented | ||
* as individual digit lists between ["0"] and ["1", "5"]. | ||
* | ||
* @template T - The list of hex digits. | ||
* | ||
* @example | ||
* ```ts | ||
* import { DigitList } from "hkt-toolbelt"; | ||
* | ||
* type Result = DigitList._$fromHex<[["7"], ["1", "1"]]>; // ["1", "2", "3"] | ||
* ``` | ||
*/ | ||
export type _$fromHex< | ||
T extends DigitList.DigitList[], | ||
/** | ||
* The unit value of the current place. Multiplies by 16 on every iteration. | ||
*/ | ||
PLACE_MUL extends DigitList.DigitList = ['1'], | ||
/** | ||
* The current sum of places that have been processed so far. | ||
*/ | ||
SUM extends DigitList.DigitList = ['0'], | ||
/** | ||
* The next place value, multiplied by 16. | ||
*/ | ||
NEXT_PLACE_MUL extends DigitList.DigitList = DigitList._$multiply< | ||
PLACE_MUL, | ||
['1', '6'] | ||
> | ||
> = T extends [ | ||
...infer Init extends DigitList.DigitList[], | ||
infer Last extends DigitList.DigitList | ||
] | ||
? _$fromHex< | ||
Init, | ||
NEXT_PLACE_MUL, | ||
DigitList._$add<SUM, DigitList._$multiply<PLACE_MUL, Last>> | ||
> | ||
: SUM | ||
|
||
/** | ||
* `_$fromHex` is a type-level function that takes in a list of hex digits | ||
* `T`, and returns a list of decimal digits. The hex digits are represented | ||
* as individual digit lists between ["0"] and ["1", "5"]. | ||
* | ||
* @template T - The list of hex digits. | ||
* | ||
* @example | ||
* ```ts | ||
* import { DigitList } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<DigitList.FromHex, [["7"], ["1", "1"]]>; // ["1", "2", "3"] | ||
* ``` | ||
*/ | ||
export interface FromHex extends Kind.Kind { | ||
f(x: Type._$cast<this[Kind._], DigitList.DigitList[]>): _$fromHex<typeof x> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { $, Test, DigitList } from '..' | ||
|
||
type ToHex_Spec = [ | ||
/** | ||
* Can convert a digit list to hex. | ||
*/ | ||
Test.Expect<$<DigitList.ToHex, ['1', '2', '3']>, [['7'], ['1', '1']]>, | ||
|
||
/** | ||
* Can convert a digit list to hex with a single digit. | ||
*/ | ||
Test.Expect<$<DigitList.ToHex, ['1']>, [['1']]>, | ||
|
||
/** | ||
* Can convert a digit list to hex zero. | ||
*/ | ||
Test.Expect<$<DigitList.ToHex, ['0']>, [['0']]> | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { Type, DigitList, Kind } from '..' | ||
|
||
/** | ||
* `_$toHex` is a type-level function that takes in a digit list `T`, and | ||
* returns a list of the hex digits of `T`, represented as individual digit | ||
* lists between ["0"] and ["1", "5"]. | ||
* | ||
* @template T - The digit list to convert. | ||
* | ||
* @example | ||
* ```ts | ||
* import { DigitList } from "hkt-toolbelt"; | ||
* | ||
* type Result = DigitList._$toHex<["1", "2", "3"]>; // [["7"], ["1", "1"]] | ||
* ``` | ||
*/ | ||
export type _$toHex< | ||
T extends DigitList.DigitList, | ||
O extends unknown[] = [], | ||
DIV = DigitList._$divide<T, ['1', '6']>, | ||
MOD = DigitList._$modulo<T, ['1', '6']> | ||
> = 0 extends 1 | ||
? never | ||
: DIV extends ['0'] | ||
? [MOD, ...O] | ||
: _$toHex<Type._$cast<DIV, DigitList.DigitList>, [MOD, ...O]> | ||
|
||
/** | ||
* `ToHex` is a type-level function that takes in a digit list `T`, and | ||
* returns a list of the hex digits of `T`, represented as individual digit | ||
* lists between ["0"] and ["1", "5"]. | ||
* | ||
* @template T - The digit list to convert. | ||
* | ||
* @example | ||
* ```ts | ||
* import { $, DigitList } from "hkt-toolbelt"; | ||
* | ||
* type Result = $<DigitList.ToHex, ["1", "2", "3"]>; // [["7"], ["1", "1"]] | ||
* ``` | ||
*/ | ||
export interface ToHex extends Kind.Kind { | ||
f(x: Type._$cast<this[Kind._], DigitList.DigitList>): _$toHex<typeof x> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { $, Kind, NaturalNumber, Test } from '..' | ||
|
||
type JuxtN_Spec = [ | ||
/** | ||
* Apply a list of n-arity kinds to a value. | ||
*/ | ||
Test.Expect< | ||
$<$<$<Kind.JuxtN, [NaturalNumber.Increment, NaturalNumber.Add]>, 1>, 5>, | ||
[2, 6] | ||
> | ||
] | ||
|
||
it('should apply a list of n-arity kinds to a value', () => { | ||
expect( | ||
Kind.juxtN([NaturalNumber.increment, NaturalNumber.add])(1)(5) | ||
).toEqual([2, 6]) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { $, Kind, Type, Function } from '..' | ||
|
||
/** | ||
* `_$juxtN` is a type-level function that takes in a list of kinds `K` and | ||
* a value `X`, and either returns a list of the results applied to `X`, or | ||
* another instance of `_$juxtN` for any remaining kinds in the resultant list. | ||
* | ||
* Arity is determined by the maximal arity of the kinds in the list. | ||
* | ||
* @template {Kind.Kind[]} K - The list of kinds to apply. | ||
* @template {unknown} X - The value to apply the kinds to. | ||
* | ||
* @example | ||
* ```ts | ||
* import { $, Kind, List } from "hkt-toolbelt"; | ||
* | ||
* type MyJuxt = Kind._$juxtN<[NaturalNumber.Increment, NaturalNumber.Add], 1>; | ||
* // ^? Kind.JuxtN_T<[2, NaturalNumber.Add_T<1>]> | ||
* | ||
* type Result = $<MyJuxt, 5>; | ||
* // ^? [2, 6] | ||
* ``` | ||
*/ | ||
export type _$juxtN<K extends unknown[], X> = { | ||
[key in keyof K]: K[key] extends Kind.Kind | ||
? $<K[key], Type._$cast<X, Kind._$inputOf<K[key]>>> | ||
: K[key] | ||
} extends infer NewK extends unknown[] | ||
? Kind.Kind<never> extends NewK[number] | ||
? JuxtN_T<NewK> | ||
: NewK | ||
: never | ||
|
||
interface JuxtN_T<K extends unknown[]> extends Kind.Kind { | ||
f(x: this[Kind._]): _$juxtN<K, typeof x> | ||
} | ||
|
||
/** | ||
* `JuxtN` is a type-level function that takes in a list of kinds `K` and | ||
* a value `X`, and either returns a list of the results applied to `X`, or | ||
* another instance of `JuxtN` for any remaining kinds in the resultant list. | ||
* | ||
* Arity is determined by the maximal arity of the kinds in the list. | ||
* | ||
* @template {Kind.Kind[]} K - The list of kinds to apply. | ||
* @template {unknown} X - The value to apply the kinds to. | ||
* | ||
* @example | ||
* ```ts | ||
* import { $, Kind, List } from "hkt-toolbelt"; | ||
* | ||
* type MyJuxt = Kind.JuxtN<[NaturalNumber.Increment, NaturalNumber.Add], 1>; | ||
* // ^? Kind.JuxtN_T<[2, NaturalNumber.Add_T<1>]> | ||
* | ||
* type Result = $<MyJuxt, 5>; | ||
* // ^? [2, 6] | ||
* ``` | ||
*/ | ||
export interface JuxtN extends Kind.Kind { | ||
f(x: Type._$cast<this[Kind._], unknown[]>): JuxtN_T<typeof x> | ||
} | ||
|
||
/** | ||
* Given a list of kinds and a value, apply the kinds to the value. If any of | ||
* the kinds result in another kind, return a new instance of `JuxtN` for the | ||
* remaining kinds and take in a new input value until all kinds have been | ||
* exhausted. | ||
* | ||
* @param {Kind.Kind[]} fx - The list of kinds to apply. | ||
* @param {unknown} x - The value to apply the kinds to. | ||
* | ||
* @example | ||
* ```ts | ||
* import { Kind, NaturalNumber } from "hkt-toolbelt"; | ||
* | ||
* const result = Kind.juxtN([NaturalNumber.increment, NaturalNumber.add])(1)(2) | ||
* // ^? [2, 3] | ||
* ``` | ||
*/ | ||
export const juxtN = ((fx: Function.Function[]) => (x: unknown) => { | ||
const results = [] | ||
let hasKindResult = false | ||
|
||
for (const f of fx) { | ||
const result = typeof f === 'function' ? f(x as never) : f | ||
|
||
if (typeof result === 'function') { | ||
hasKindResult = true | ||
} | ||
|
||
results.push(result) | ||
} | ||
|
||
if (hasKindResult) { | ||
return juxtN(results as Function.Function[]) | ||
} | ||
|
||
return results | ||
}) as unknown as Kind._$reify<JuxtN> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { $, Test, List } from '..' | ||
|
||
type PadEnd_Spec = [ | ||
/** | ||
* Can pad a list to a desired length. | ||
*/ | ||
Test.Expect<$<$<$<List.PadEnd, 8>, 0>, []>, [0, 0, 0, 0, 0, 0, 0, 0]>, | ||
|
||
/** | ||
* Padding a list longer than the specified length results in the original list. | ||
*/ | ||
Test.Expect<$<$<$<List.PadEnd, 2>, '0'>, [1, 2, 3]>, [1, 2, 3]>, | ||
|
||
/** | ||
* Can pad a list to a desired length. | ||
*/ | ||
Test.Expect<$<$<$<List.PadEnd, 6>, 0>, [1, 2, 3]>, [1, 2, 3, 0, 0, 0]> | ||
] | ||
|
||
it('should pad a list to a desired length', () => { | ||
expect(List.padEnd(8)(0)([])).toEqual([0, 0, 0, 0, 0, 0, 0, 0]) | ||
}) | ||
|
||
it('padding a list longer than the specified length results in the original list', () => { | ||
expect(List.padEnd(2)('0')([1, 2, 3])).toEqual([1, 2, 3]) | ||
}) | ||
|
||
it('can pad a list to a desired length', () => { | ||
expect(List.padEnd(6)(0)([1, 2, 3])).toEqual([1, 2, 3, 0, 0, 0]) | ||
}) |
Oops, something went wrong.