Skip to content

Commit

Permalink
Merge pull request #14 from Gipphe/use-haskellish
Browse files Browse the repository at this point in the history
style: use es6
  • Loading branch information
Gipphe committed Jul 11, 2019
2 parents 265d79e + 3b05785 commit 6fdad44
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 203 deletions.
57 changes: 2 additions & 55 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,4 @@
module.exports = {
root: true,
extends: ['./node_modules/sanctuary-style/eslint-es3.json'],
rules: {
strict: 'off',
indent: [
'error',
'tab',
{
'SwitchCase': 1,
'FunctionDeclaration': { 'parameters': 'first' },
'FunctionExpression': { 'parameters': 'first' },
'CallExpression': { 'arguments': 'first' },
'ArrayExpression': 'first',
'ObjectExpression': 'first',
'ignoredNodes': [
'CallExpression',
'CallExpression > *',
'CallExpression > ArrowFunctionExpression ArrowFunctionExpression > *',
'CallExpression > FunctionExpression > BlockStatement',
'ConditionalExpression',
'MemberExpression'
],
},
],
'no-tabs': 'off',
},
overrides: [
{
files: ['*.md'],
globals: {
'$': false,
'Cons': false,
'Descending': false,
'Just': false,
'Left': false,
'Nil': false,
'Nothing': false,
'Pair': false,
'R': false,
'Right': false,
'S': false,
'Sum': false,
'localStorage': false,
'sanctuary': false,
'window': false
},
rules: {
'comma-dangle': ['error', 'always-multiline'],
'indent': ['off'],
'no-eval': ['off'],
'no-extra-semi': ['off'],
'no-unused-vars': ['error', { 'varsIgnorePattern': '^([$]|S)$' }]
}
}
]
}
extends: ['@gipphe/eslint-config-haskellish'],
};
184 changes: 54 additions & 130 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,127 +1,59 @@
// UMD setup ripped straight from Q.js

(function(definition) {
'use strict';

// This file will function properly as a <script> tag, or a module
// using CommonJS and NodeJS or RequireJS module formats. In
// Common/Node/RequireJS, the module exports the caseof API and when
// executed as a simple <script>, it creates a caseof global instead.

/* istanbul ignore next */

// Montage Require
if (typeof bootstrap === 'function') {
/* global bootstrap: false */
bootstrap ('promise', definition);

// CommonJS
} else if (typeof exports === 'object' && typeof module === 'object') {
module.exports = definition ();

// RequireJS
} else if (typeof define === 'function' && define.amd) {
define (definition);

// SES (Secure EcmaScript)
} else if (typeof ses !== 'undefined') {
/* global ses: true */
if (!ses.ok ()) {
return;
} else {
ses.makeCaseof = definition;
}

// <script>
} else if (typeof window !== 'undefined' || typeof self !== 'undefined') {
/* global window: true */
// Prefer window over self for add-on scripts. Use self for
// non-windowed contexts.
var global = typeof window !== 'undefined' ? window : self;

// Get the `window` object, save the previous caseof global
// and initialize caseof as a global.
var previousCaseof = global.caseof;
global.caseof = definition ();

// Add a noConflict function so caseof can be removed from the
// global namespace.
global.caseof.noConflict = function() {
global.caseof = previousCaseof;
return this;
};

} else {
throw new Error ('This environment was not anticipated by caseof. ' +
'Please file a bug.');
}

} (function() {
'use strict';

function assertIsFunction(x, msg) {
// assertIsFunction :: a -> String -> Undefined!
const assertIsFunction = x => msg => {
if (typeof x !== 'function') {
throw new Error (msg);
}
}
};

function assertIsFunctionAndExplain(x) {
assertIsFunction (x, 'First argument must be a function');
}
// assertIsFunctionAndExplain :: a -> Undefined!
const assertIsFunctionAndExplain = x => {
assertIsFunction (x) ('First argument must be a function');
};

function assertWasCalledWithOneParameterAndExplain(x, name) {
// assertWasCalledWithOneParameterAndExplain :: a -> String -> Undefined!
const assertWasCalledWithOneParameterAndExplain = x => name => {
if (typeof x !== 'undefined') {
throw new Error (name + ': ' + name + ' is a curried ' +
'function, and as such only takes one argument. ' +
'Received two. The proper way to call ' + name + ': ' +
'"fn (x) (y)", instead of ' +
'"fn (x, y)"');
}
}
};

function assertMatchesNotEmpty(x) {
// assertMatchesNotEmpty :: [a] -> Undefined!
const assertMatchesNotEmpty = x => {
if (x.length === 0) {
throw new Error ('None of the cases matches the value');
}
}

function when(matches) {
return function(value) {
return function(pred, x) {
assertWasCalledWithOneParameterAndExplain
(x, 'when');
assertIsFunction (pred, 'when: predicate must be a function');
return function(handler) {
assertIsFunction (handler, 'when: handler must be a function');
if (pred (value)) {
matches.push (handler (value));
}
};
};
};

// when :: [a] -> a -> (a -> Bool) -> (a -> b) -> Undefined!
const when = matches => value => (pred, x) => {
assertWasCalledWithOneParameterAndExplain (x) ('when');
assertIsFunction (pred) ('when: predicate must be a function');
return handler => {
assertIsFunction (handler) ('when: handler must be a function');
if (pred (value)) {
matches.push (handler (value));
}
};
}

function lazyWhen(continuationFn) {
return function(matches) {
return function(value) {
return function(pred, x) {
assertWasCalledWithOneParameterAndExplain
(x, 'when');
assertIsFunction (pred, 'when: predicate must be a function');
return function(handler) {
assertIsFunction
(handler, 'when: handler must be a function');
if (!continuationFn (matches)) {
return;
}
if (pred (value)) {
matches.push (handler (value));
}
};
};
};
};

// lazyWhen :: ([a] -> Bool) -> [a] -> a -> (a -> Bool) -> Undefined!
const lazyWhen = continuationFn => matches => value => (pred, x) => {
assertWasCalledWithOneParameterAndExplain (x) ('when');
assertIsFunction (pred) ('when: predicate must be a function');
return handler => {
assertIsFunction (handler) ('when: handler must be a function');
if (!continuationFn (matches)) {
return;
}
if (pred (value)) {
matches.push (handler (value));
}
};
}
};

//# otherwise :: a -> Boolean
//.
Expand All @@ -142,9 +74,7 @@ function lazyWhen(continuationFn) {
//. . }) (23)
//. 0
//. ```
function otherwise() {
return true;
}
const otherwise = () => true;

//# caseOfAll :: ((a -> Boolean) -> (a -> b) -> Undefined) -> a -> Array b
//.
Expand Down Expand Up @@ -173,23 +103,23 @@ function otherwise() {
//. . }) (0)
//. ! Error None of the cases matches the value
//. ```
function caseOfAll(specFn, x) {
assertWasCalledWithOneParameterAndExplain (x, 'caseOfAll');
const caseOfAll = (specFn, x) => {
assertWasCalledWithOneParameterAndExplain (x) ('caseOfAll');
assertIsFunctionAndExplain (specFn);

return function(value) {
var matches = [];
var boundWhen = when (matches) (value);
return value => {
const matches = [];
const boundWhen = when (matches) (value);
specFn (boundWhen);
assertMatchesNotEmpty (matches);
return matches;
};
}
};

//# caseOf :: ((a -> Boolean) -> (a -> b) -> Undefined) -> a -> b
//.
//. Returns the result of the first matching case. This function is lazy, and
//. only the first matching handler is run.
//. Returns the result of the first matching case. This function is lazy,
//. and only the first matching handler is run.
//.
//. ```javascript
//. > caseOf ((when) => {
Expand Down Expand Up @@ -227,24 +157,18 @@ function caseOfAll(specFn, x) {
//. . }) ('quack')
//. ! Error: None of the cases matches the value
//. ```
function caseOf(specFn, x) {
'use strict';
assertWasCalledWithOneParameterAndExplain (x, 'caseOf');
const caseOf = (specFn, x) => {
assertWasCalledWithOneParameterAndExplain (x) ('caseOf');
assertIsFunctionAndExplain (specFn);
return function(value) {
var matches = [];
var boundWhen = lazyWhen
(function(m) { return m.length === 0; })
(matches)
(value);
return value => {
const matches = [];
const boundWhen = lazyWhen (m => m.length === 0) (matches) (value);
specFn (boundWhen);
assertMatchesNotEmpty (matches);
return matches[0];
};
}
};
caseOf.all = caseOfAll;
caseOf.otherwise = otherwise;

return caseOf;

}));
module.exports = caseOf;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
"release": "yarn lint && yarn test && yarn standard-version"
},
"devDependencies": {
"@gipphe/eslint-config-haskellish": "^0.1.3",
"ava": "^2.2.0",
"coveralls": "^3.0.2",
"eslint": "5.16.0",
"nyc": "^14.1.1",
"sanctuary-style": "^3.0.0",
"standard-version": "^6.0.1",
"transcribe": "^1.1.2"
},
Expand Down
Loading

0 comments on commit 6fdad44

Please sign in to comment.