diff --git a/package.json b/package.json index a10f6ff..582aa1c 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,6 @@ "uglify-js": "^2.7.3" }, "dependencies": { - "fantasy-land": "^2.0.0" + "fantasy-land": "^2.1.0" } } diff --git a/src/Promise.js b/src/Promise.js index 50d2984..d0b8d4c 100644 --- a/src/Promise.js +++ b/src/Promise.js @@ -64,6 +64,14 @@ class Core { return this.concat(p) } + [fl.alt] (p) { + return this.or(p) + } + + static [fl.zero] () { + return never() + } + // @deprecated The name concat is deprecated, use or() instead. concat (b) { return this.or(b) diff --git a/test/fantasyland-laws-test.js b/test/fantasyland-laws-test.js index 47acd7c..167adcd 100644 --- a/test/fantasyland-laws-test.js +++ b/test/fantasyland-laws-test.js @@ -1,5 +1,7 @@ import { describe, it } from 'mocha' +import assert from 'assert' import { fulfill, Promise } from '../src/main' +import { isNever } from '../src/inspect' import { assertSame } from './lib/test-util' import * as Functor from 'fantasy-land/laws/functor' import * as Chain from 'fantasy-land/laws/chain' @@ -7,86 +9,98 @@ import * as Apply from 'fantasy-land/laws/apply' import * as Applicative from 'fantasy-land/laws/applicative' import * as Semigroup from 'fantasy-land/laws/semigroup' import * as Monoid from 'fantasy-land/laws/monoid' -import fl from 'fantasy-land' +import * as Alt from 'fantasy-land/laws/alt' +import * as Plus from 'fantasy-land/laws/plus' +import * as Alternative from 'fantasy-land/laws/alternative' -const id = x => x +const assertIsNever = x => assert(isNever(x)) describe('fantasyland laws', () => { describe('functor', () => { it('should satisfy identity', () => { - return Functor.identity(fulfill, assertSame, {}) + return Functor.identity(fulfill)(assertSame)({}) }) it('should satisfy composition', () => { const f = x => x + 'f' const g = x => x + 'g' - return Functor.composition(fulfill, assertSame, f, g, 'x') - }) - - it('should be covered', () => { - return fulfill()[fl.map](id) + return Functor.composition(fulfill)(assertSame)(f)(g)('x') }) }) describe('apply', () => { it('should satisfy composition', () => { - return Apply.composition(fulfill, assertSame, {}) - }) - - it('should be covered', () => { - return fulfill()[fl.ap](fulfill(id)) + return Apply.composition(Promise)(assertSame)({}) }) }) describe('applicative', () => { it('should satisfy identity', () => { - return Applicative.identity(Promise, assertSame, {}) + return Applicative.identity(Promise)(assertSame)({}) }) it('should satisfy homomorphism', () => { - return Applicative.homomorphism(Promise, assertSame, {}) + return Applicative.homomorphism(Promise)(assertSame)({}) }) it('should satisfy interchange', () => { - return Applicative.interchange(Promise, assertSame, {}) + return Applicative.interchange(Promise)(assertSame)({}) }) + }) - it('should be covered', () => { - return Promise[fl.of](undefined) + describe('chain', () => { + it('should satisfy associativity', () => { + return Chain.associativity(Promise)(assertSame)({}) }) }) - describe('chain', () => { + describe('semigroup', () => { it('should satisfy associativity', () => { - return Chain.associativity(fulfill, assertSame, {}) + return Semigroup.associativity(fulfill)(assertSame)({}) + }) + }) + + describe('monoid', () => { + it('should satisfy rightIdentity', () => { + return Monoid.rightIdentity(Promise)(assertSame)({}) }) - it('should be covered', () => { - return fulfill()[fl.chain](fulfill) + it('should satisfy leftIdentity', () => { + return Monoid.leftIdentity(Promise)(assertSame)({}) }) }) - describe('semigroup', () => { + describe('alt', () => { it('should satisfy associativity', () => { - return Semigroup.associativity(fulfill, assertSame, {}) + return Alt.associativity(assertSame)(fulfill(1))(fulfill(2))(fulfill(3)) }) - it('should be covered', () => { - return fulfill()[fl.concat](fulfill()) + it('should satisfy distributivity', () => { + return Alt.distributivity(assertSame)(fulfill(1))(fulfill(-1))(x => x + 1) }) }) - describe('monoid', () => { + describe('plus', () => { + it('should satisfy leftIdentity', () => { + return Plus.leftIdentity(Promise)(assertSame)(fulfill({})) + }) + it('should satisfy rightIdentity', () => { - return Monoid.rightIdentity(Promise, assertSame, {}) + return Plus.rightIdentity(Promise)(assertSame)(fulfill({})) }) - it('should satisfy leftIdentity', () => { - return Monoid.leftIdentity(Promise, assertSame, {}) + it('should satisfy annihilation', () => { + return Plus.annihilation(Promise)(assertIsNever)(x => x + 1) + }) + }) + + describe('alternative', () => { + it('should satisfy distributivity', () => { + return Alternative.distributivity(p => p.then(x => assert.strictEqual(1, x)))(fulfill(0))(fulfill(x => x + 1))(fulfill(x => x - 1)) }) - it('should be covered', () => { - return Promise[fl.empty]().concat(fulfill()) + it('should satisfy annihilation', () => { + return Plus.annihilation(Promise)(assertIsNever)(fulfill({})) }) }) })