Skip to content

Commit

Permalink
Merge branch 'docs' of https://github.com/evilsoft/crocks into naviga…
Browse files Browse the repository at this point in the history
…tion-api
  • Loading branch information
Ryan Stegmann committed Feb 6, 2017
2 parents facce30 + 5745f6b commit 1d0c505
Show file tree
Hide file tree
Showing 97 changed files with 1,937 additions and 255 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ node_modules
.node-version
dist/

.coveralls.yml
.nyc_output
coverage

*.log

.DS_Store
Expand Down
4 changes: 4 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ docs
.jshintignore
.jshintrc

coverage
.coveralls.yml
.nyc_output/

.node-version
*.log
.DS_Store
Expand Down
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
language: node_js

node_js:
- '7'
- '6'
- '5'
- '4.2'

install:
- npm install

script:
- npm test

after_success:
- npm run coverage
184 changes: 160 additions & 24 deletions README.md

Large diffs are not rendered by default.

23 changes: 22 additions & 1 deletion crocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ const helpers = {
not: require('./helpers/not'),
once: require('./helpers/once'),
pipe: require('./helpers/pipe'),
prop: require('./helpers/prop'),
propPath: require('./helpers/propPath'),
safe: require('./helpers/safe'),
safeLift: require('./helpers/safeLift'),
tap: require('./helpers/tap'),
tryCatch: require('./helpers/tryCatch'),
unless: require('./helpers/unless'),
Expand All @@ -65,6 +68,7 @@ const monoids = {
const pointFree = {
ap: require('./pointfree/ap'),
bimap: require('./pointfree/bimap'),
both: require('./pointfree/both'),
chain: require('./pointfree/chain'),
coalesce: require('./pointfree/coalesce'),
concat: require('./pointfree/concat'),
Expand Down Expand Up @@ -97,18 +101,34 @@ const pointFree = {
}

const predicates = {
hasKey: require('./predicates/hasKey'),
isApplicative: require('./predicates/isApplicative'),
isApply: require('./predicates/isApply'),
isArray: require('./predicates/isArray'),
isBoolean: require('./predicates/isBoolean'),
isDefined: require('./predicates/isDefined'),
isEmpty: require('./predicates/isEmpty'),
isFoldable: require('./predicates/isFoldable'),
isFunction: require('./predicates/isFunction'),
isFunctor: require('./predicates/isFunctor'),
isInteger: require('./predicates/isInteger'),
isMonad: require('./predicates/isMonad'),
isMonoid: require('./predicates/isMonoid'),
isNil: require('./predicates/isNil'),
isNumber: require('./predicates/isNumber'),
isObject: require('./predicates/isObject'),
isSameType: require('./predicates/isSameType'),
isSetoid: require('./predicates/isSetoid'),
isSemigroup: require('./predicates/isSemigroup'),
isString: require('./predicates/isString'),
isTraversable: require('./predicates/isTraversable')
}

const transforms = {
eitherToAsync: require('./transforms/eitherToAsync'),
eitherToMaybe: require('./transforms/eitherToMaybe'),
maybeToAsync: require('./transforms/maybeToAsync'),
maybeToEither: require('./transforms/maybeToEither')
}

module.exports = Object.assign(
Expand All @@ -118,5 +138,6 @@ module.exports = Object.assign(
helpers,
monoids,
pointFree,
predicates
predicates,
transforms
)
39 changes: 38 additions & 1 deletion crocks.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ const mreduceMap = require('./helpers/mreduceMap')
const not = require('./helpers/not')
const once = require('./helpers/once')
const pipe = require('./helpers/pipe')
const prop = require('./helpers/prop')
const propPath = require('./helpers/propPath')
const safe = require('./helpers/safe')
const safeLift = require('./helpers/safeLift')
const tap = require('./helpers/tap')
const tryCatch = require('./helpers/tryCatch')
const unless = require('./helpers/unless')
Expand All @@ -43,6 +46,7 @@ const sequence = require('./pointfree/sequence')
const swap = require('./pointfree/swap')
const traverse = require('./pointfree/traverse')

const both = require('./pointfree/both')
const cons = require('./pointfree/cons')
const either = require('./pointfree/either')
const evalWith = require('./pointfree/evalWith')
Expand Down Expand Up @@ -88,18 +92,32 @@ const Max = require('./monoids/Max')
const Prod = require('./monoids/Prod')
const Sum = require('./monoids/Sum')

const hasKey = require('./predicates/hasKey')
const isApplicative = require('./predicates/isApplicative')
const isApply = require('./predicates/isApply')
const isArray = require('./predicates/isArray')
const isBoolean = require('./predicates/isBoolean')
const isDefined = require('./predicates/isDefined')
const isEmpty = require('./predicates/isEmpty')
const isFoldable = require('./predicates/isFoldable')
const isFunction = require('./predicates/isFunction')
const isFunctor = require('./predicates/isFunctor')
const isInteger = require('./predicates/isInteger')
const isMonad = require('./predicates/isMonad')
const isMonoid = require('./predicates/isMonoid')
const isNil = require('./predicates/isNil')
const isNumber = require('./predicates/isNumber')
const isObject = require('./predicates/isObject')
const isSameType = require('./predicates/isSameType')
const isSemigroup = require('./predicates/isSemigroup')
const isSetoid = require('./predicates/isSetoid')
const isString = require('./predicates/isString')
const isTraversable = require('./predicates/isTraversable')

const eitherToAsync = require('./transforms/eitherToAsync')
const eitherToMaybe = require('./transforms/eitherToMaybe')
const maybeToAsync = require('./transforms/maybeToAsync')
const maybeToEither = require('./transforms/maybeToEither')

test('entry', t => {
t.equal(crocks.toString(), '[object Object]', 'is an object')
Expand All @@ -112,6 +130,7 @@ test('entry', t => {
t.equal(crocks.reverseApply, reverseApply, 'provides the T combinator (reverseApply)')
t.equal(crocks.substitution, substitution, 'provides the S combinator (substitution)')

t.equal(crocks.branch, branch, 'provides the branch function')
t.equal(crocks.compose, compose, 'provides the compose function')
t.equal(crocks.curry, curry, 'provides the curry function')
t.equal(crocks.curryN, curryN, 'provides the curryN function')
Expand All @@ -126,7 +145,10 @@ test('entry', t => {
t.equal(crocks.not, not, 'provides the not function')
t.equal(crocks.once, once, 'provides the once function')
t.equal(crocks.pipe, pipe, 'provides the pipe function')
t.equal(crocks.prop, prop, 'provides the prop function')
t.equal(crocks.propPath, propPath, 'provides the propPath function')
t.equal(crocks.safe, safe, 'provides the safe function')
t.equal(crocks.safeLift, safeLift, 'provides the safeLift function')
t.equal(crocks.tap, tap, 'provides the tap function')
t.equal(crocks.tryCatch, tryCatch, 'provides the tryCatch function')
t.equal(crocks.unless, unless, 'provides the unless function')
Expand All @@ -144,7 +166,7 @@ test('entry', t => {
t.equal(crocks.swap, swap, 'provides the swap point-free function')
t.equal(crocks.traverse, traverse, 'provides the traverse point-free function')

t.equal(crocks.branch, branch, 'provides the branch point-free function')
t.equal(crocks.both, both, 'provides the both point-free function')
t.equal(crocks.cons, cons, 'provides the cons point-free function')
t.equal(crocks.either, either, 'provides the either point-free function')
t.equal(crocks.evalWith, evalWith, 'provides the evalWith point-free function')
Expand Down Expand Up @@ -190,17 +212,32 @@ test('entry', t => {
t.equal(crocks.Prod, Prod, 'provides the Prod monoid')
t.equal(crocks.Sum, Sum, 'provides the Sum monoid')

t.equal(crocks.hasKey, hasKey, 'provides the hasKey function')
t.equal(crocks.isApplicative, isApplicative, 'provides the isApplicative function')
t.equal(crocks.isApply, isApply, 'provides the isApply function')
t.equal(crocks.isArray, isArray, 'provides the isArray function')
t.equal(crocks.isBoolean, isBoolean, 'provides the isBoolean function')
t.equal(crocks.isDefined, isDefined, 'provides the isDefined function')
t.equal(crocks.isEmpty, isEmpty, 'provides the isEmpty function')
t.equal(crocks.isFoldable, isFoldable, 'provides the isFoldable function')
t.equal(crocks.isFunction, isFunction, 'provides the isFunction function')
t.equal(crocks.isFunctor, isFunctor, 'provides the isFunctor function')
t.equal(crocks.isInteger, isInteger, 'provides the isInteger function')
t.equal(crocks.isMonad, isMonad, 'provides the isMonad function')
t.equal(crocks.isMonoid, isMonoid, 'provides the isMonoid function')
t.equal(crocks.isNil, isNil, 'provides the isNil function')
t.equal(crocks.isNumber, isNumber, 'provides the isNumber function')
t.equal(crocks.isObject, isObject, 'provides the isObject function')
t.equal(crocks.isSameType, isSameType, 'provides the isSameType function')
t.equal(crocks.isSemigroup, isSemigroup, 'provides the isSemigroup function')
t.equal(crocks.isSetoid, isSetoid, 'provides the isSetoid function')
t.equal(crocks.isString, isString, 'provides the isString function')
t.equal(crocks.isTraversable, isTraversable, 'provides the isTraversable function')

t.equal(crocks.eitherToAsync, eitherToAsync, 'provides the eitherToAsync function')
t.equal(crocks.eitherToMaybe, eitherToMaybe, 'provides the eitherToMaybe function')
t.equal(crocks.maybeToAsync, maybeToAsync, 'provides the maybeToAsync function')
t.equal(crocks.maybeToEither, maybeToEither, 'provides the maybeToEither function')

t.end()
})
15 changes: 12 additions & 3 deletions crocks/Arrow.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

const isFunction = require('../predicates/isFunction')

const isType = require('../internal/isType')
const isSameType = require('../predicates/isSameType')
const _inspect = require('../internal/inspect')

const compose = require('../helpers/compose')
Expand Down Expand Up @@ -37,7 +37,7 @@ function Arrow(runWith) {
constant(`Arrow${_inspect(value())}`)

function concat(m) {
if(!(m && isType(type(), m))) {
if(!(isSameType(Arrow, m))) {
throw new TypeError('Arrow.concat: Arrow required')
}

Expand Down Expand Up @@ -87,10 +87,19 @@ function Arrow(runWith) {
})
}

function both() {
return Arrow(function(x) {
if(!(x && x.type && x.type() === Pair.type())) {
throw TypeError('Arrow.both: Pair required for inner argument')
}
return x.bimap(runWith, runWith)
})
}

return {
inspect, type, value, runWith,
concat, empty, map, contramap,
promap, first, second
promap, first, second, both
}
}

Expand Down
29 changes: 29 additions & 0 deletions crocks/Arrow.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,3 +401,32 @@ test('Arrow second', t => {

t.end()
})

test('Arrow both', t => {
t.ok(isFunction(Arrow(noop).both), 'provides a both function')

const m = Arrow(x => x + 1)

const runWith = bindFunc(m.both().runWith)

t.throws(runWith(undefined), TypeError, 'throws with undefined as inner argument')
t.throws(runWith(null), TypeError, 'throws with null as inner argument')
t.throws(runWith(0), TypeError, 'throws with falsey number as inner argument')
t.throws(runWith(1), TypeError, 'throws with truthy number as inner argument')
t.throws(runWith(''), TypeError, 'throws with falsey string as inner argument')
t.throws(runWith('string'), TypeError, 'throws with truthy string as inner argument')
t.throws(runWith(false), TypeError, 'throws with false as inner argument')
t.throws(runWith(true), TypeError, 'throws with true as inner argument')
t.throws(runWith([]), TypeError, 'throws with an array as inner argument')
t.throws(runWith({}), TypeError, 'throws with an object as inner argument')

t.doesNotThrow(runWith(Pair.of(2)), 'does not throw when inner value is a Pair')

const result = m.both().runWith(Pair(10, 10))

t.equal(result.type(), 'Pair', 'returns a Pair')
t.equal(result.fst(), 11, 'applies the function to the first element of a pair')
t.equal(result.snd(), 11, 'applies the function to the snd element of a pair')

t.end()
})
48 changes: 43 additions & 5 deletions crocks/Async.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
/** @license ISC License (c) copyright 2016 original and current authors */
/** @license ISC License (c) copyright 2017 original and current authors */
/** @author Ian Hofmann-Hicks (evil) */

const isFoldable= require('../predicates/isFoldable')
const isFunction = require('../predicates/isFunction')

const _inspect = require('../internal/inspect')
const isType = require('../internal/isType')
const argsArray = require('../internal/argsArray')
const isSameType = require('../predicates/isSameType')

const constant = require('../combinators/constant')
const composeB = require('../combinators/composeB')

const sequence = require('../pointfree/sequence')

const once = require('../helpers/once')
const mreduceMap = require('../helpers/mreduceMap')

const All = require('../monoids/All')

const allAsyncs =
mreduceMap(All, x => isSameType(Async, x))

const _type =
constant('Async')
Expand All @@ -20,6 +30,32 @@ const _of =
const _rejected =
x => Async((reject, _) => reject(x))

function all(asyncs) {
if(!(isFoldable(asyncs) && allAsyncs(asyncs))) {
throw new TypeError('Async.all: Foldable structure of Asyncs required')
}

return sequence(Async.of, asyncs)
}

function fromNode(fn, ctx) {
if(!isFunction(fn)) {
throw new TypeError('Async.fromNode: CPS function required')
}

return function() {
const args = argsArray(arguments)

return Async((reject, resolve) => {
fn.apply(ctx,
args.concat(
(err, data) => err ? reject(err) : resolve(data)
)
)
})
}
}

const hasPromiseInterface =
x => x && isFunction(x.then) && isFunction(x.catch)

Expand Down Expand Up @@ -61,7 +97,7 @@ function Async(fn) {

function fork(reject, resolve) {
if(!isFunction(reject) || !isFunction(resolve)) {
throw new TypeError('Async.fork: reject and resolve functions required')
throw new TypeError('Async.fork: Reject and resolve functions required')
}

fn(reject, resolve)
Expand Down Expand Up @@ -127,7 +163,7 @@ function Async(fn) {
var fnDone = false
var valueDone = false

if(!isType(type(), m)) {
if(!isSameType(Async, m)) {
throw new TypeError('Async.ap: Async required')
}

Expand Down Expand Up @@ -167,7 +203,7 @@ function Async(fn) {
fork(reject, function(x) {
const m = fn(x)

if(!isType(type(), m)) {
if(!isSameType(Async, m)) {
throw new TypeError('Async.chain: Function must return another Async')
}

Expand All @@ -187,5 +223,7 @@ Async.type = _type
Async.of = _of
Async.rejected = _rejected
Async.fromPromise = fromPromise
Async.fromNode = fromNode
Async.all = all

module.exports = Async
Loading

0 comments on commit 1d0c505

Please sign in to comment.