-
Notifications
You must be signed in to change notification settings - Fork 7
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 #28 from Jozty/dev-ss
add function - andThen
- Loading branch information
Showing
15 changed files
with
396 additions
and
5 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import curryN from "./utils/curry_n.ts" | ||
import { Func, Curry2 } from "./utils/types.ts" | ||
import { assertPromise } from "./utils/assert.ts" | ||
|
||
function _andThen(f: Func, p: any) { | ||
assertPromise('andThen', p) | ||
return p.then(f) | ||
} | ||
|
||
/** | ||
* Returns the result of applying the onSuccess function to the value inside | ||
* a successfully resolved promise. This is useful for working with promises | ||
* inside function compositions. | ||
*/ | ||
export const andThen: Curry2<Func, any, Promise<any>> = curryN(2, _andThen) |
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 { Predicate2, Curry2 } from "./utils/types.ts" | ||
import curryN from "./utils/curry_n.ts" | ||
import { slice } from "./slice.ts" | ||
|
||
function _groupWith<T>(predicate: Predicate2<T | string>, functor: T[] | string) { | ||
const result: T[][] | string[] = [] | ||
const len = functor.length | ||
let i = 0 | ||
while(i < len) { | ||
let j = i + 1 | ||
while(j < len && predicate(functor[j - 1], functor[j])) j++ | ||
result.push(slice(i, j, functor) as (T[] & string)) | ||
i = j | ||
} | ||
return result | ||
} | ||
|
||
export const groupWith: Curry2<Predicate2, any[] | string, any[][] | string[]> = curryN(2, _groupWith) |
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,13 @@ | ||
import { nth } from './nth.ts' | ||
|
||
/** | ||
* Returns the first element of the given list or string. In some libraries | ||
* this function is named `first`. | ||
* | ||
* Fae.head(['fi', 'fo', 'fum']); //=> 'fi' | ||
* Fae.head([]); //=> undefined | ||
* | ||
* Fae.head('abc'); //=> 'a' | ||
* Fae.head(''); //=> '' | ||
*/ | ||
export const head = nth(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,56 @@ | ||
import { isNumber } from './utils/is.ts' | ||
import curryN from "./utils/curry_n.ts" | ||
import { Curry2 } from "./utils/types.ts" | ||
import { equals } from './equals.ts' | ||
|
||
function _indexOf<T>(value: T, list: T[]) { | ||
switch(typeof value) { | ||
case 'number': { | ||
if(value === 0) { | ||
// handles +0 and -0 | ||
const inf = 1 / value | ||
for (let i = 0; i < list.length; i++) { | ||
const x: any = list[i] | ||
if(x === 0 && 1 / x === inf) return i | ||
} | ||
return -1 | ||
} | ||
else if(value !== value) { | ||
// handles NaN | ||
for (let i = 0; i < list.length; i++) { | ||
const x: any = list[i] | ||
if(isNaN(x)) return i | ||
} | ||
return -1 | ||
} | ||
} | ||
case 'string': | ||
case 'boolean': | ||
case 'function': | ||
case 'undefined': | ||
return list.indexOf(value) | ||
|
||
case 'object': | ||
if (value === null) { | ||
return list.indexOf(value) | ||
} | ||
} | ||
|
||
|
||
let idx = -1 | ||
list.forEach((a, i) => idx = equals(value, a) ? i : idx) | ||
return idx | ||
} | ||
|
||
/** | ||
* Returns the position of the first occurrence of `value` in `list`, or -1 | ||
* if the item is not included in the array. [`Fae.equals`](#equals) is used to | ||
* determine equality. | ||
* | ||
* Fae.indexOf(3, [1,2,3,4]); //=> 2 | ||
* Fae.indexOf(10, [1,2,3,4]); //=> -1 | ||
* Fae.indexOf(0, [1, 2, 3, 0, -0, NaN]); //=> 3 | ||
* Fae.indexOf(-0, [1, 2, 3, 0, -0, NaN]); //=> 4 | ||
* Fae.indexOf(NaN, [1, 2, 3, 0, -0, NaN]); //=> 5 | ||
*/ | ||
export const indexOf: Curry2<any, any[], number> = curryN(2, _indexOf) |
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,16 @@ | ||
|
||
export function it(fun: Function) { | ||
return async function() { | ||
let done: Function = () => void 0 | ||
const p = new Promise(resolve => { | ||
let d = () => resolve() | ||
done = d | ||
}) | ||
await fun(done) | ||
await p | ||
} | ||
} | ||
|
||
export type Tests = { | ||
[desc: string]: () => Promise<void> | ||
} |
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,68 @@ | ||
import { it, Tests } from './_async.ts' | ||
import { describe, it as itS} from "./_describe.ts" | ||
import { | ||
andThen, | ||
compose, | ||
pipe, | ||
inc, | ||
} from '../mod.ts' | ||
import { eq, thr } from "./utils/utils.ts" | ||
|
||
const tests: Tests = { | ||
"should invoke then on the promise with the function passed to it": it( | ||
async (done: Function) => { | ||
const p = new Promise(resolve => { | ||
setTimeout(() => { | ||
resolve(1) | ||
}, 100) | ||
}) | ||
andThen( | ||
function (n) { | ||
eq(n, 1) | ||
done() | ||
}, | ||
p | ||
) | ||
} | ||
), | ||
|
||
"should flatten promise returning functions": it( | ||
async (done: Function) => { | ||
const incAndWrap = compose(Promise.resolve.bind(Promise), inc) | ||
const asyncAddThree = pipe(incAndWrap, andThen(incAndWrap), andThen(incAndWrap)) | ||
|
||
andThen((result) => { | ||
eq(result, 4) | ||
done() | ||
})(asyncAddThree(1)) | ||
} | ||
), | ||
|
||
"should not dependent on a particular promise implementation": it( | ||
async (done: Function) => { | ||
const thennable = { | ||
then: function(f: Function) { | ||
return f(42) | ||
} | ||
} | ||
|
||
const f = function(n: number) { | ||
eq(n, 42) | ||
done() | ||
} | ||
|
||
andThen(f, thennable) | ||
} | ||
), | ||
} | ||
|
||
describe('andThen', () => { | ||
itS('throws a typeError if the then method does not exist', () => { | ||
thr(() => andThen(inc, 1), '`andThen` expected a Promise, received 1') | ||
|
||
}) | ||
}) | ||
|
||
for(let desc in tests) { | ||
Deno.test(desc, tests[desc]) | ||
} |
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 @@ | ||
deno test specs/andThen.spec.ts |
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,40 @@ | ||
import { describe, it } from "./_describe.ts" | ||
import { groupWith, equals } from '../mod.ts' | ||
import { eq } from "./utils/utils.ts" | ||
|
||
describe('groupWith', () => { | ||
|
||
it('should split the list into groups according to the grouping function', () => { | ||
eq(groupWith(equals, [1, 2, 2, 3]), [[1], [2, 2], [3]]) | ||
eq(groupWith(equals, [1, 1, 1, 1]), [[1, 1, 1, 1]]) | ||
eq(groupWith(equals, [1, 2, 3, 4]), [[1], [2], [3], [4]]) | ||
}) | ||
|
||
it('should split the list into "streaks" testing adjacent elements', () => { | ||
// @ts-ignore | ||
const isConsecutive = function(a, b) { return a + 1 === b; } | ||
eq(groupWith(isConsecutive, []), []) | ||
eq(groupWith(isConsecutive, [4, 3, 2, 1]), [[4], [3], [2], [1]]) | ||
eq(groupWith(isConsecutive, [1, 2, 3, 4]), [[1, 2, 3, 4]]) | ||
eq(groupWith(isConsecutive, [1, 2, 2, 3]), [[1, 2], [2, 3]]) | ||
eq(groupWith(isConsecutive, [1, 2, 9, 3, 4]), [[1, 2], [9], [3, 4]]) | ||
}) | ||
|
||
it('should return an empty array if given an empty array', () => { | ||
eq(groupWith(equals, []), []) | ||
}) | ||
|
||
// TODO: | ||
// it('can be turned into the original list through concatenation', () => { | ||
// var list = [1, 1, 2, 3, 4, 4, 5, 5] | ||
// eq(R.unnest(groupWith(equals, list)), list) | ||
// eq(R.unnest(groupWith(R.complement(equals), list)), list) | ||
// eq(R.unnest(groupWith(R.T, list)), list) | ||
// eq(R.unnest(groupWith(R.F, list)), list) | ||
// }) | ||
|
||
it('should also work on strings', () => { | ||
eq(groupWith(equals)('Mississippi'), ['M','i','ss','i','ss','i','pp','i']) | ||
}) | ||
|
||
}) |
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,26 @@ | ||
import { describe, it } from "./_describe.ts" | ||
import { head } from '../mod.ts' | ||
import { eq, thr } from "./utils/utils.ts" | ||
|
||
describe('head', () => { | ||
|
||
it('should return the first element of an ordered collection', () => { | ||
eq(head([1, 2, 3]), 1) | ||
eq(head([2, 3]), 2) | ||
eq(head([3]), 3) | ||
eq(head([]), undefined) | ||
|
||
eq(head('abc'), 'a') | ||
eq(head('bc'), 'b') | ||
eq(head('c'), 'c') | ||
eq(head(''), '') | ||
}) | ||
|
||
it('should throw if applied to null or undefined', () => { | ||
// @ts-ignore | ||
thr(() => head(null), 'The functor should be an array like or iterable/iterator') | ||
// @ts-ignore | ||
thr(() => head(undefined), 'The functor should be an array like or iterable/iterator') | ||
}) | ||
|
||
}) |
Oops, something went wrong.