nodash 0.13.0 api documentation

This is the API documentation for nodash 0.13.0.

Don't miss the Appendix.

Boolean

AND && Prelude: &&

Boolean → Boolean → Boolean

Boolean "and". This is effectively just making the && operator available as a curried function.

Not to be confused with the lower case and.

Example:

AND(true, true) === true
AND(false)(true) === false
foldl(AND, true, [ true, false ]) === false

Haskell Definition:

True && True = True
_    && _    = False

Source:

function AND(a, b) {
  return a && b;
}

bool

Boolean → Boolean → Boolean

Fold on Boolean. bool(x, y, c) evaluates to x if c is false and to y otherwise.

Haskell Definition:

bool no yes condition = case condition of
  True -> yes
  False -> no

Source:

function bool(no, yes, bool) {
  return bool ? yes : no;
}

not Prelude: not

Boolean → Boolean

Negates a boolean value.

This is basically JavaScripts unary prefix operator ! defined as a function.

Example:

not(true) === false

Haskell Definition:

not False = True
not _     = False

Source:

function not(value) {
  return !value;
}

OR || Prelude: ||

Boolean → Boolean → Boolean

Booleanm "or". This is effectively just making the && operator available as a curried function.

Not to be confused with the lower case or.

Example:

OR(false, true) === true
OR(false)(false) === false
foldl(OR, false, [ true, false ]) === true

Haskell Definition:

False && False = False
_     && _     = True

Source:

function OR(a, b) {
  return a || b;
}

Char

chr

Integer → Char

Source:

function chr(x) {
  return String.fromCharCode(x);
}

isAsciiLetter

String → Boolean

Determines whether the given String or Character is an ascii letter, that is: Matching the regular expression /^[a-zA-Z]+$/.

Example:

isAsciiLetter('X') === true
isAsciiLetter('@') === false
isAsciiLetter('8') === false

Source:

function isAsciiLetter(x) {
  return /^[a-zA-Z]+$/.test(x);
}

isLetter

Char → Boolean

Source:

function isLetter(x) {
  var xUpper = x.toUpperCase();
  var xLower = x.toLowerCase();
  for (var i = 0; i < x.length; i += 1) {
    if (xUpper[i] === xLower[i]) {
      return false;
    }
  }
  return true;
}

isLower

String → Boolean

Source:

function isLower(x) {
  var xUpper = x.toUpperCase();
  var xLower = x.toLowerCase();
  for (var i = 0; i < x.length; i += 1) {
    if (xUpper[i] === xLower[i] || x[i] !== xLower[i]) {
      return false;
    }
  }
  return true;
}

isNumeric isDigit

Something → Boolean

Source:

function isNumeric(thing) {
  return /^[0-9]+$/.test(thing);
}

isUpper

String → Boolean

Source:

function isUpper(x) {
  var xUpper = x.toUpperCase();
  var xLower = x.toLowerCase();
  for (var i = 0; i < x.length; i += 1) {
    if (xUpper[i] === xLower[i] || x[i] !== xUpper[i]) {
      return false;
    }
  }
  return true;
}

ord

Char → Integer

Source:

function ord(x) {
  return x.charCodeAt(0);
}

Control

async

Source:

function async(f) {
  return function () {
    try {
      var callback = arguments[arguments.length - 1];
      var result = f.apply(null, [].slice.call(arguments, 0, arguments.length - 1));
      setImmediate(function () { callback(null, result); });
    } catch (e) {
      setImmediate(function () { callback(e); });
    }
  };
}

pipe

Source:

function pipe() {
  var functions, intermediateResult, callback;
  var error = null;
  if (isArray(arguments[0])) {
    functions = arguments[0];
    callback = arguments[1];
  } else {
    functions = arguments;
  }
  if (functions.length > 0) {
    if (isFunction(functions[0])) {
      intermediateResult = functions[0]();
    } else {
      intermediateResult = functions[0];
    }
    for (var i = 1; i < functions.length; i += 1) {
      try {
        intermediateResult = functions[i](intermediateResult);
      } catch (err) {
        error = err;
      }
    }
  }
  if (isFunction(callback)) {
    callback(error, intermediateResult);
  } else if (error) {
    throw error;
  }
  return intermediateResult;
}

run

Source:

function run(specification) {
  // this function does its own currying.
  if (arguments.length === 2) {
    run(specification)(arguments[1]);
    return;
  }

  // if spec is an array, translate to object spec
  if (isArray(specification)) {
    var prev = null;
    var newSpec = {};
    each(function (func, taskName) {
      newSpec[taskName] = prev === null ? func : [ prev, func ];
      prev = taskName;
    }, specification);
    specification = newSpec;
  }

  var tasks = {};
  var initial = [];

  // prepare tasks specification.
  each(function (spec, name) {
    var dependencies = [];
    var func = null;
    if (isArray(spec)) {
      dependencies = init(spec);
      func = last(spec);
    } else {
      if (isArray(spec.depends)) {
        dependencies = spec.depends;
      }
      func = spec;
    }

    var task = {
      func: func,
      args: dependencies,
      depends: {},
      enables: tasks[name] ? tasks[name].enables : {}
    };
    each(function (dependency) {
      task.depends[dependency] = true;
      if (!tasks[dependency]) {
          tasks[dependency] = { enables: {} };
      }
      tasks[dependency].enables[name] = true;
    }, dependencies);
    tasks[name] = task;
  }, specification);

  // check spec for unmet dependencies
  var unmetDependencies = [];
  each(function (task, taskName) {
    each(function (_, dependency) {
      if (!specification[dependency]) {
        unmetDependencies.push([ taskName, dependency ]);
      }
    }, task.depends);
  }, tasks);

  function mkError(message) {
    return function (callback) {
      setImmediate(function () {
        callback(message);
      });
    };
  }

  if (!isEmpty(unmetDependencies)) {
    return mkError({
      message: 'unmet dependencies',
      details: map(function (detail) {
        return '`' +
          detail[0] + '` depends on `' +
          detail[1] + '` which is not defined';
      }, unmetDependencies)
    });
  }

  // build initial set
  each(function (task, taskName) {
    if (isEmpty(task.depends)) {
      initial.push(taskName);
    }
  }, tasks);

  if (isEmpty(initial)) {
    return mkError({
      message: 'no initial task',
      details: 'There is no task without any dependencies.'
    });
  }

  // check spec for cycles
  var cycles = [];
  each(function (taskName) {

    var visited = {};
    var path = [];

    function visit(node) {
      path.push(node);
      if (visited[node]) {
        cycles.push(map(id, path));
      } else {
        visited[node] = true;
        each(visit, Object.keys(tasks[node].enables));
      }
      delete visited[path.pop()];
    }

    visit(taskName);

  }, initial);

  if (!isEmpty(cycles)) {
    cycles = map(function (cycle) {
      cycle = dropWhile(NEQ(last(cycle)), cycle);
      return reverse(cycle);
    }, cycles);
    return mkError({
      message: 'cycle detected',
      details: map(intercalate(' -> '), cycles)
    });
  }

  return function _runTasks(callback) {

    var depends = {},
        toGo = length(tasks),
        results = map(function (task, taskName) {
      return { toGo: length(task.enables) };
    }, tasks);

    function callbackHandle(taskName) {
      return function (error, result) {
        if (!error) {
          results[taskName].result = result;
        } else {
          results[taskName].error = error;
        }

        // clean up results if need be
        each(function (_, dependency) {
          results[dependency].toGo -= 1;
          if (results[dependency].toGo === 0) {
            delete results[dependency];
          }
        }, tasks[taskName].depends);

        toGo -= 1;
        if (toGo === 0) {
          // clean results object
          each(function (result) {
            delete result.toGo;
          }, results);
          callback(null, results);
        } else {
          each(function (_, next) {
            delete depends[next][taskName];
            if (isEmpty(depends[next])) {
              execute(next);
            }
          }, tasks[taskName].enables);
        }
      };
    }

    function execute(taskName) {
      var task = tasks[taskName],
          callback = callbackHandle(taskName),
          dependenciesFailed = false,
          args = map(function (dependency) {
            if (results[dependency].error) {
              dependenciesFailed = true;
            }
            return results[dependency].result;
          }, task.args);

      if (dependenciesFailed && isFunction(task.func.runOnError)) {
        var tempResult = {};
        each(function (dependency) {
          var result = results[dependency];
          var stubResult = {};
          if (result.error) {
            stubResult.error = result.error;
          } else {
            stubResult.result = result.result;
          }
          tempResult[dependency] = stubResult;
        }, task.args);
        tempResult = task.func.runOnError(tempResult) || tempResult;
        args = map(function (dependency) {
          return tempResult[dependency].result;
        }, task.args);
      }

      args.push(callback);

      setImmediate(function _executeTask() {
        if (dependenciesFailed && !task.func.runOnError) {
          callback({ message: 'dependencies failed' });
        } else {
          var f = task.func;
          if (isObject(f)) {
            f = f.func;
          }
          try {
            f.apply(null, args);
          } catch (e) {
            callback(e);
          }
        }
      });
    }

    each(function (task, taskName) {
      depends[taskName] = clone(task.depends);
    }, tasks);

    each(execute, initial);
  };
}

Collection

Nodash knows four different types of collections:

Those are typically distinguished as belonging to either Array-like or List-like. A JavaScript String is an Array-like type, a Stream is a List-like type. Array and Strings are the native types from JavaScript, List and Stream are introduced by Nodash.

Properties of the various type, where x is a value of the given type, i is an index, and n is the number of elements.

Array String List Stream
evaluation strict strict lazy lazy
mutability mutable immutable immutable immutable
typeOf(x) array string list stream
elements arbitrary characters arbitrary arbitrary
limit finite finite finite infinite
at(i, x) O(1) O(1) O(n) O(n)

all Prelude: all

(a → Bool) → [a] → Bool

Applied to a predicate and a list, all determines if all elements of the list satisfy the given predicate.

Example:

all(even, [1, 2, 3]) === false
all(lte(3), [1, 2, 3]) === true

This function works with strings too:

all(isDigit, "123") === true

Source:

function all(p, xs) {
  for (var i = 0; i < xs.length; i++) {
    if (!p(xs[i])) {
      return false;
    }
  }
  return true;
}

and Prelude: and

[Bool] → Bool

Returns the conjunction of a list of booleans, i.e. it returns true iff all the elements in the list evaluate to true.

NOTE: This, the lowercase and, is not the binary boolean operator, which is the uppercase AND.

Example:

and([true, true, true]) === true
and([true, false, true]) === false
and([1, 1, 1]) === true
and([]) === false

Source:

var and = /* this is a composed function */

foldl foldl'reduceLeft Prelude: foldl'

(a → b → b) → b → [a] → b

Left-associative fold of a structure.

Haskell Definition:

foldl :: (a -> b -> b) -> b -> [a] -> b
foldl f s xs = case xs of
    [] -> s
    (x : xs) -> foldl f (f x s) xs

Source:

function foldl(f, x, xs) {
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      for (var i = 0; i < xs.length; i += 1) {
        x = f(x, xs[i]);
      }
      return x;
    case 'list':
      while (!xs.isEmpty()) {
        x = f(xs.head(), x);
        xs = xs.tail();
      }
      return x;
  }
}

foldr reduceRight Prelude: foldr

(b → a → b) → b → [a] → b

Right-associative fold of a structure.

Haskell Definition:

foldr :: (b -> a -> b) -> b -> [a] -> b
foldr f s xs = case xs of
    [] -> s
    (x : xs) -> f (foldr f s xs) x

Source:

function foldr(f, x, xs) {
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      for (var i = xs.length - 1; i >= 0; i -= 1) {
        x = f(xs[i], x);
      }
      return x;
    case 'list':
      if (xs.isEmpty()) {
        return x;
      }
      return f(foldr(f, x, xs.tail()), xs.head());
  }
}

isInfixOf Prelude: isInfixOf

[a] → [a] → Boolean

The isInfixOf function takes two lists and returns true iff the first list is contained, wholly and intact, anywhere within the second.

It uses an implementation of the Knuth-Morris-Pratt algorithm and works with both strings and arrays.

Source:

function isInfixOf(infix, string) {
  return indexOf(infix, string) >= 0;
}

isPrefixOf Prelude: isPrefixOf

[a] → [a] → Boolean

The isPrefixOf function takes two lists and returns true iff the first list is a prefix of the second.

Source:

function isPrefixOf(prefix, string) {
  for (var j = 0; j < prefix.length; j++) {
    if (string[j] !== prefix[j]) {
      return false;
    }
  }
  return true;
}

isSuffixOf Prelude: isSuffixOf

[a] → [a] → Boolean

The isSuffixOf function takes two lists and returns true iff the first list is a suffix of the second.

Source:

function isSuffixOf(suffix, string) {
  for (var i = 0; i < suffix.length; i++) {
    if (string[string.length - suffix.length + i] !== suffix[i]) {
      return false;
    }
  }
  return true;
}

permutations Prelude: permutations

[a] → [[a]]

Generates a list of permutations using the Steinhaus-Johnson-Trotter algorithm.

This function returns an array of all the permutations if an array or a string is passed, or a lazily evaluated list if a list is passed.

Example using a string:

permutations('abc')
// → [ 'abc', 'acb', 'cab', 'cba', 'bca', 'bac' ]

Example using a list:

permutations(lazy([ 7, 4 ]))
// → [ [ 7, 4 ], [ 4, 7 ] ]

Source:

function permutations(thing) {
  switch (typeOf(thing)) {
    case 'array':
    case 'string':
      return sjt.all(thing);
    case 'list':
      return generateList(listToArray(thing));
    default:
      error(TypeError);
  }
}

sum Prelude: sum

[Number] → Number

The sum function computes the sum of a list of numbers.

Example:

sum([1, 4, 9]) === 14

Source:

var sum = /* this is a composed function */

zip Prelude: zip

Source:

var zip = /* this is a composed function */

zip3 Prelude: zip3

Source:

var zip3 = /* this is a composed function */

zip4 Prelude: zip4

Source:

var zip4 = /* this is a composed function */

zipWith Prelude: zipWith

Source:

function zipWith(f, as, bs) {
  var length = Math.min(as.length, bs.length);
  var zs = [];
  for (var i = 0; i < length; i++) {
    zs[i] = f(as[i], bs[i]);
  }
  return zs;
}

zipWith3 Prelude: zipWith3

Source:

function zipWith3(f, as, bs, cs) {
  var length = minimum([as.length, bs.length, cs.length]);
  var zs = [];
  for (var i = 0; i < length; i++) {
    zs[i] = f(as[i], bs[i], cs[i]);
  }
  return zs;
}

zipWith4 Prelude: zipWith4

Source:

function zipWith4(f, as, bs, cs, ds) {
  var length = minimum([as.length, bs.length, cs.length, ds.length]);
  var zs = [];
  for (var i = 0; i < length; i++) {
    zs[i] = f(as[i], bs[i], cs[i], ds[i]);
  }
  return zs;
}

Either

Either

Source:

function Either() {
  fail();
}

isLeft

Either a b → Boolean

Source:

var isLeft = /* this is a composed function */

isRight

Either a b → Boolean

Source:

var isRight = /* this is a composed function */

Left

Source:

function Left(value) {
  if (!(this instanceof Left)) {
    return new Left(value);
  }
  this.value = idf(value);
}

lefts

Source:

var lefts = /* this is a composed function */

partitionEithers

Source:

function partitionEithers(xs) {
  return tuple(lefts(xs), rights(xs));
}

Right

Source:

function Right(value) {
  if (!(this instanceof Right)) {
    return new Right(value);
  }
  this.value = idf(value);
}

rights

Source:

var rights = /* this is a composed function */

Function

apply $ Prelude: $

Haskell Definition:

apply func arg = func arg

Source:

function apply(f, x) {
  return f(x);
}

compose . Prelude: .

(b → c) → (a → b) → a → c

Function composition.

Example:

var f = compose(plus(10), times(2));
f(3) === 16

Haskell Definition:

compose g f = \x -> g (f x)

Source:

function compose(f, g, x) {
  return f(g(x));
}

compose2

Source:

function compose2(f, g, x, y) {
  return f(g(x, y));
}

const const_constant Prelude: const

Haskell Definition:

const = \a _ -> a

Source:

function const(a, b) {
  return a;
}

curry Prelude: curry

Source:

function curry(f) {
  return curried(function (a, b) {
    return f(tuple(a, b));
  });
}

flip Prelude: flip

(a → b → c) → (b → a → c)

flip(f) takes its (first) two arguments in the reverse order of f.

Example:

minus(10, 8) === 2
var subtract = flip(minus)
subtract(10, 8) === -2

Haskell Definition:

flip f = \a b -> f b a

Source:

function flip(f) {
  return curried(function (b, a) {
    return f(a, b);
  });
}

id Prelude: id

a → a

Identity function.

Example:

id(7) === 7

Haskell Definition:

id = \x -> x

Source:

function id(x) { return x; }

idf

Source:

function idf(x) {
  return function () {
    return x;
  };
}

invoke

Source:

function invoke(f) {
  return f();
}

on

(b → b → c) → (a → b) → a → a → c

Example:

var xs = [
    { firstName: 'Jonathan', secondName: 'Müller' },
    { firstName: 'Benjamin', secondName: 'Bamboo' }
];
var sortByFirstName = sortBy(on(compare, select('firstName')), xs);

Haskell Definition:

(.*.) `on` f = \x y -> f x .*. f y

Source:

function on(g, f, a, b) {
  return g(f(a), f(b));
}

uncurry Prelude: uncurry

Source:

function uncurry(f) {
  return function (t) {
    return f(fst(t), snd(t));
  };
}

List

arrayToString

Source:

function arrayToString(array) {
  return array.join('');
}

lazy arrayToList

Source:

function lazy(val) {
  if (isFunction(val)) {
    return new Thunk(val);
  }
  function generator(i) {
    if (i < val.length) {
      return new List(val[i], new Thunk(function () {
        return generator(i + 1);
      }));
    }
    return emptyList();
  }
  return generator(0);
}

List

new List(head, tail) :: a → [a] → [a]

Lists are immutable singly-linked sequences.

Methods:

.head() → a
Extract the first element in the list.
.tail() → List a
Extract the rest of the list.

Lists are typically not constructed by user code with this constructor, but with builers such as arrayToList.

The purpose of the List type is to implement lazy evaluation. Internally the head and the tail of a list may actually be Thunks which are evaluated only if you call .head() or .tail() respectively.

To construct lazy lists, use lazy.

Example:

var xs = new List(38, new List(42, emptyList()))

console.log(xs.head()) // 38
console.log(xs.tail().head()) // 42

head and tail are functional forms of .head() and .tail().

var xs = lazy([1, 2, 3, 4, 5]);
console.log(head(xs)); // 1
console.log(head(tail(xs))); // 2

Haskell Definition:

data List a = EmptyList | Cons { head :: a, tail :: (List a) }

Source:

function List(head, tail) {
  var self = this;
  this.head = function () {
    if (is(Thunk, head)) {
      var value = head.get();
      self.head = head.get;
      return value;
    }
    return head;
  };
  this.tail = function () {
    if (is(Thunk, tail)) {
      var value = tail.get();
      self.tail = tail.get;
      return value;
    }
    return tail;
  };
}

listToArray

Source:

function listToArray(xs) {
  var array = [];
  each(function (x) {
    array.push(x);
  }, xs);
  return array;
}

listToString

Source:

var listToString = /* this is a composed function */

range ..

Source:

function range(from, to) {
  return rangeStep(1, from, to);
}

rangeStep

Source:

function rangeStep(step, from, to) {
  step = from < to ? step : -step;
  to = step > 0 ? Math.floor(to) : Math.ceil(to);
  var current = from;
  function gen() {
    current += step;
    return new List(current, current === to ? emptyList : new Thunk(gen));
  }
  return new List(from, new Thunk(gen));
}

singleton

Source:

function singleton(thing) {
  return new List(thing, emptyList);
}

Maybe

catMaybes

Source:

var catMaybes = /* this is a composed function */

isJust

Source:

function isJust(thing) {
  return thing !== null && thing !== undefined;
}

isNothing

Source:

function isNothing(thing) {
  return !isJust(thing);
}

mapMaybe

Source:

var mapMaybe = /* this is a composed function */

maybe Prelude: maybe

Source:

function maybe(def, fun, value) {
  if (value === null || value === undefined) {
    return def;
  }
  return fun(value);
}

maybeToList

Source:

function maybeToList(thing) {
  if (isJust(thing)) {
    return singleton(thing);
  }
  return emptyList();
}

Math

abs Prelude: abs

Number → Number

Returns the absolute (positive, non-negative) value of a number.

Example:

abs(9) === 9
abs(-3) === 3

Haskell Definition:

abs x | x >= 0 = x
      | x <  0 = -x

Source:

function abs() { [native code] }

acos Prelude: acos

Number → Number

Source:

function acos() { [native code] }

acosh Prelude: acosh

Number → Number

Source:

function acosh(x) {
  return Math.log(x + Math.sqrt(x * x - 1));
}

add +ADDplusPLUS Prelude: +

Number → Number → Number

Source:

function add(a, b) {
  return a + b;
}

asin Prelude: asin

Number → Number

Source:

function asin() { [native code] }

asinh Prelude: asinh

Number → Number

Source:

function asinh(x) {
  if (x === -Infinity) {
    return x;
  } else {
    return Math.log(x + Math.sqrt(x * x + 1));
  }
}

atan Prelude: atan

Number → Number

Source:

function atan() { [native code] }

atanh Prelude: atanh

Number → Number

Source:

function atanh(x) {
  return Math.log((1 + x) / (1 - x)) / 2;
}

ceiling Prelude: ceiling

Number → Number

ceiling x returns the least integer not less than x.

Source:

function ceil() { [native code] }

cos Prelude: cos

Number → Number

Source:

function cos() { [native code] }

cosh Prelude: cosh

Number → Number

Source:

function cosh(x) {
  return (Math.exp(x) + Math.exp(-x)) / 2;
}

div Prelude: div

Number → Number

Source:

function div(a, b) {
  return Math.floor(a / b);
}

divMod Prelude: divMod

Number → Number → (Number, Number)

Source:

function divMod(a, b)  {
  return tuple(div(a, b), mod(a, b));
}

even Prelude: even

Number → Bool

Source:

function even(x) {
  return (x % 2) === 0;
}

exp Prelude: exp

Number → Number

Source:

function exp() { [native code] }

floor Prelude: floor

Number → Number

floor x returns the greatest integer not greater than x.

Source:

function floor() { [native code] }

frac / Prelude: /

Number → Number → Number

Source:

function frac(a, b) {
  return a / b;
}

gcd Prelude: gcd

Number → Number → Number

Source:

function gcd(a, b) {
  var c;
  while (b !== 0) {
    c = rem(a, b);
    a = b;
    b = c;
  }
  return a;
}

lcm Prelude: lcm

Number → Number → Number

Source:

function lcm(a, b) {
  if (a === 0 || b === 0) {
    return 0;
  }
  return Math.abs(quot(a, gcd(a, b)) * b);
}

log Prelude: log

Number → Number

Source:

function log() { [native code] }

logBase Prelude: logBase

Number → Number → Number

Haskell Definition:

logBase x y = log y / log x

Source:

function logBase(a, b) {
  return Math.log(a) / Math.log(b);
}

minus -MINUS Prelude: -

Number → Number → Number

Source:

function minus(a, b) {
  return a - b;
}

mod Prelude: mod

Number → Number → Number

Source:

function mod(a, b) {
  var q = quot(a, b);
  var r = rem(a, b);
  return signum(r) === -signum(b) ? r + b : r;
}

mul *MULtimesTIMES Prelude: *

Number → Number → Number

Source:

function mul(a, b) {
  return a * b;
}

negate Prelude: negate

Number → Number

Source:

function negate(x) {
  return -x;
}

odd Prelude: odd

Number → Boolean

Source:

function odd(x) {
  return (x % 2) !== 0;
}

pow **^^^ Prelude: ^^

Haskell Definition:

x ** y = exp (log x * y)

Source:

function pow() { [native code] }

properFraction Prelude: properFraction

Number → (Number, Number)

properFraction takes a real fractional number x and returns a pair (n, f) such that x = n + f, and: n is an integral number with the same sign as x; and f is a fraction with the same type and sign as x, and with absolute value less than 1.

Source:

function properFraction(x) {
  var num = truncate(x);
  return tuple(num, -(num - x));
}

quot Prelude: quot

Number → Number → Number

Source:

function quot(a, b) {
  var r = a / b;
  return r >= 0 ? Math.floor(r) : Math.ceil(r);
}

quotRem Prelude: quotRem

Number → Number → (Number, Number)

Source:

function quotRem(a, b) {
  return tuple(quot(a, b), rem(a, b));
}

recip Prelude: recip

Haskell Definition:

recip = 1 / x

Source:

function recip(x) {
  return 1 / x;
}

rem Prelude: rem

Number → Number → Number

Source:

function rem(a, b) {
  return a % b;
}

round Prelude: round

Number → Number

round x returns the nearest integer to x; the even integer if x is equidistant between two integers.

Source:

function round(x) {
  var fraction = properFraction(x);
  var n = fraction[0];
  var m = fraction[1] < 0 ? n - 1 : n + 1;
  switch (signum(Math.abs(fraction[1]) - 0.5)) {
    case -1:
      return n;
    case 0:
      return n % 2 === 0 ? n : m;
    case 1:
      return m;
  }
}

signum Prelude: signum

Number → Number

Haskell Definition:

signum x | x >  0 = 1
         | x == 0 = 0
         | x <  0 = -1

Source:

function signum(x) {
  if (x > 0) {
    return 1;
  } else if (x === 0) {
    return 0;
  }
  return -1;
}

sin Prelude: sin

Number → Number

Source:

function sin() { [native code] }

sqrt Prelude: sqrt

Number → Number

Source:

function sqrt() { [native code] }

sub subtract Prelude: subtract

Number → Number

Source:

function sub(a, b) {
  return b - a;
}

tan Prelude: tan

Number → Number

Haskell Definition:

tan x = sin x / cos x

Source:

function tan() { [native code] }

tanh Prelude: tanh

Number → Number

Haskell Definition:

tanh x = sinh x / cosh x

Source:

function tanh(x) {
  if (x === Infinity) {
    return 1;
  } else if (x === -Infinity) {
    return -1;
  } else {
    return (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x));
  }
}

truncate Prelude: truncate

Number → Number

truncate x returns the integer nearest x between zero and x.

Source:

function truncate(x) {
  switch (signum(x)) {
  case -1:
    return Math.ceil(x);
  case 1:
    return Math.floor(x);
  }
  return 0;
}

Nodash

install

Source:

function install(mountpoint) {
  var options = arguments[1];
  var nodashObject = Nodash;
  var prefix = '';
  var postfix = '';
  if (!mountpoint) {
    return Nodash;
  }
  if (options) {
    nodashObject = makeNodash(options);
  }
  if (isArray(mountpoint)) {
    if (isString(mountpoint[0])) {
      prefix = [].shift.call(mountpoint);
    }
    if (isString(mountpoint[1])) {
      postfix = mountpoint[1];
    }
    mountpoint = mountpoint[0] || {};
  }
  each(function (func, name) {
    if (name[0] === '_') {
      return;
    }
    var key = prefix + name + postfix;
    if (!(key in mountpoint)) {
      mountpoint[key] = func;
    }
  }, nodashObject);
  return mountpoint;
}

register

Source:

function register() {
  var args = [].slice.call(arguments);
  
  if (arguments.length === 1) {
    switch (typeof args[0]) {
    case 'object':
      if (Array.isArray(args[0])) {
        registerInjected(args[0].slice());
      } else {
        registerLib(args[0]);
      }
      break;
    case 'function':
      register(args[0].call(Nodash));
      break;
    }
    return;
  }
  var func = args.pop();
  var aliases = [];
  args.forEach(function (arg) {
    [].push.apply(aliases, arg.split(/ +/));
  });
  var name = null;
  for (var i = 0; i < aliases.length; i += 1) {
    if (/^[a-z0-9]+$/i.test(aliases[i])) {
      name = aliases[i];
      break;
    }
  }
  __metadata[name] = {
    aliases: aliases,
    definition: func 
  };
  if (!/^[A-Z]/.test(name)) {
    func = curried(func);
  }
  aliases.forEach(function (alias) {
    Nodash[alias] = func;
  });
}

Pattern

match

MatchSpec → Any → MatchResult

match(spec, value) matches value against the spec, returning what was captured in the spec.

A MatchSpec is an array of arrays. Every array in the spec must have two elements: [ 0: Pattern, 1: Result ]. The first Pattern that matches value will yield the associated Result. If Result is a function it will be invoked with an object of all captured variables in the Pattern and the result will be returned, otherwise the Result itself.

Example:

var matchJohn = match([
  [ { firstName: 'John' }, 'John is a fine name' ],
  [ { firstName: '$firstName' },
    function (result) {
      return result.$firstName + ' is also a fine name'; } ]
]);

console.log(matchJohn({ firstName: 'John', lastName: 'Doe' }));
// → 'John is a fine name'

console.log(matchJohn({ firstName: 'Johnathan', lastName: 'X' }));
// → 'Jonathan is also a fine name'

Source:

function match(pattern, arg) {
  for (var i = 0; i < pattern.length; i += 1) {
    var result = {};
    var p = pattern[i];
    if (matchR(p[0], arg, result)) {
      if (typeof p[1] === 'function') {
        return p[1](result);
      }
      return p[1];
    }
  }
}

Object

each

Source:

function each(f, xs) {
  if (is(List, xs)) {
    while (!xs.isEmpty()) {
      f(xs.head());
      xs = xs.tail();
    }
  } else if (isArray(xs) || isString(xs)) {
    for (var i = 0; i < xs.length; i++) {
      f(xs[i], i);
    }
  } else if (isObject(xs)) {
    var ks = Object.keys(xs);
    for (var j = 0; j < ks.length; j += 1) {
      f(xs[ks[j]], ks[j]);
    }
  }
}

keys

Source:

function keys() { [native code] }

values

Source:

function values(object) {
  var values = [];
  each(function (value) {
    values.push(value);
  }, object);
  return values;
}

Stream

cycle Prelude: cycle

Source:

function cycle(xs) {
  if (isArray(xs)) {
    xs = lazy(xs);
  }
  function generator(ys) {
    if (ys.isEmpty()) {
      ys = xs;
    }
    return function () {
      return tuple(ys.head(), generator(ys.tail()));
    };
  }
  return new Stream(generator(xs));
}

iterate Prelude: iterate

Source:

function iterate(f, seed) {
  function generator(seed) {
    return function () {
      var newSeed = f(seed);
      return tuple(seed, generator(newSeed));
    };
  }
  return new Stream(generator(seed));
}

repeat Prelude: repeat

Source:

function repeat(x) {
  function generator() {
    return tuple(x, generator);
  }
  return new Stream(generator);
}

Stream stream

new Stream(generator)

Streams are immutable, lazily evaluated, infinite Lists.

Methods:

.head() → a
Extract the first element of this stream.
.tail() → List a
Extract the rest of the stream.

Source:

function Stream(generator) {
  if (!(this instanceof Stream)) {
    return new Stream(generator);
  }
  var thunk = new Thunk(generator);
  var self = this;
  this.head = function () {
    var value = thunk.get().fst();
    self.head = idf(value);
    return value;
  };
  this.tail = function () {
    var value = thunk.get().snd();
    switch (typeOf(value)) {
      case 'list':
      case 'stream':
        break;
      case 'function':
        value = new Stream(value);
        break;
      default:
        error(TypeError);
    }
    self.tail = idf(value);
    return value;
  };
}

until Prelude: until

Source:

function until(p, f, v) {
  while (!p(v)) {
    v = f(v);
  }
  return v;
}

String

lines Prelude: lines

Source:

function lines(string) {
  var result = string.split(/\n/);
  if (result[result.length - 1].length === 0) {
    delete result[result.length - 1];
  }
  return result;
}

unlines Prelude: unlines

Source:

function unlines(lines) {
  return lines.join('\n');
}

unwords Prelude: unwords

Source:

function unwords(words) {
  return words.join(' ');
}

words Prelude: words

Source:

function words(string) {
  return string.split(/[\n\r\v\t ]/);
}

Tuple

fst Prelude: fst

(a, b) → b

Extract the first component of a pair.

Tuples also have a fst() method which does the same thing, but this function is exposing that method as a function.

Haskell Definition:

fst (a, _) = a

Source:

function fst(t) {
  return t.fst();
}

objectToArray

Object → [(String, Any)]

Turns an object into an associative list of tuples.

The objects keys are the first components of the tuples, the values the second components.

eq( objectToArray({ a: 17, b: 20 }), [ tuple('a', 17), tuple('b', 20) ]) === true

Source:

function objectToArray(obj) {
  var arr = [];
  each(function (val, key) {
    arr.push(new Tuple(key, val));
  }, obj);
  return arr;
}

snd Prelude: snd

(a, b) → b

Extract the second component of a pair.

Tuples also have a fst() method which does the same thing, but this function is exposing that method as a function.

Haskell Definition:

snd (_, b) = b

Source:

function snd(t) {
  return t.snd();
}

Tuple

new Tuple(first, second) :: a → b → (a, b)

Tuples are immutable pairs of a first and a second components.

Methods:

.fst() → a
Retrieves the first component of this tuple.
.snd() → b
Retrieves the second component of this tuple.

Example:

var t = new Tuple(4711, 8080);
console.log(t.fst()); // 4711
console.log(t.snd()); // 8080

fst and snd are functional forms of .fst() and .snd().

tuple is a convenience method for omitting new:

var t = tuple(4711, 8080);
console.log(fst(t)); // 4711
console.log(snd(t)); // 8080
var extractFirsts = map(fst);
console.log(extractFirsts([
    tuple(4711, 8080),
    tuple(3000, 4444)
])); // [ 4711, 3000 ]

Haskell Definition:

data Tuple a b = Tuple { fst :: a, snd :: b }

Source:

function Tuple(fst, snd) {
  if (!(this instanceof Tuple)) {
    return new Tuple(fst, snd);
  }

  this.fst = idf(fst);
  this.snd = idf(snd);

  freeze(this);
}

tuple , Prelude: ,

Source:

function tuple(first, second) {
  return new Tuple(first, second);
}

tuple3 ,,

Source:

function tuple3(first, second, third) {
  return tuple(first, tuple(second, third));
}

tuple4 ,,,

Source:

function tuple4(first, second, third, fourth) {
  return tuple3(first, second, tuple(third, fourth));
}

tuplesToObject

[(String, Any)] → Object

Turns an associative list of tuples into an object.

The first components of the tuples are the keys, the second components the corresponding values.

Example:

eq( tuplesToObject([ tuple('a', 2), tuple('b', 3) ]), { a: 2, b: 3 }) === true

Source:

function tuplesToObject(xs) {
  var obj = {};
  each(function (t) {
    obj[t.fst()] = t.snd();
  }, xs);
  return obj;
}

Type

classOf

Any → String

Determines the property of the internal [[Class]] attribute, normalized to lower case.

Example:

classOf(new Date()) === 'date'
classOf(null) === 'null'
classOf([]) === 'array'

function f() {
    return classOf(arguments)
}
f() === 'arguments'

Source:

function classOf(thing) {
  var exactType = toString.call(thing);
  return exactType.slice(8, exactType.length - 1).toLowerCase();
}

is

Source:

function is(type, thing) {
  return thing instanceof type;
}

isArguments

Any → Boolean

Source:

function isArguments(thing) {
  return toString.call(thing) === '[object Arguments]';
}

isArray

Any → Boolean

Determines whether something is an array or not. This is exactly the same as Array.isArray.

Example:

isArray([]) === true
isArray({}) === false
isArray(new Array(3)) === true
isArray(undefined) === false
isArray(3) === false

Source:

function isArray() { [native code] }

isBoolean

Any → Boolean

Returns true if the argument is a boolean value, otherwise false.

Example:

isBoolean(true) === true
isBoolean(false) === false
isBoolean({}) === false
isBoolean(undefined) === false
isBoolean(0) === false
isBoolean(1) === false
isBoolean("true") === false

Source:

function isBoolean(thing) {
  return typeof thing === 'boolean';
}

isDate

Any → Boolean

Source:

function isDate(thing) {
  return toString.call(thing) === '[object Date]';
}

isEmpty null_ Prelude: null

Any → Boolean

Source:

function isEmpty(xs) {
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      return xs.length === 0;
    case 'list':
    case 'stream':
      return xs.isEmpty();
    default:
      for (var _ in xs) {
        return false;
      }
      return true;
  }
}

isFunction

Any → Boolean

Source:

function isFunction(thing) {
  return typeof thing === 'function';
}

isInteger

Any → Boolean

Returns true is the argument is an integral number.

Numbers in JavaScript are floating point values and there is no proper integer type. This function can be used to check whether a given number could be cast to an integer without truncating.

isInteger(7) === true
isInteger(7.0) === true
isInteger(7.3) === false

Source:

function isInteger(thing) {
  return isNumber(thing) && !isNaN(thing) &&
    thing - Math.floor(thing) === 0 &&
    thing !== Infinity && thing !== -Infinity;
}

isNull

Any → Boolean

Source:

function isNull(thing) {
  return toString.call(thing) === '[object Null]';
}

isNumber

Source:

function isNumber(thing) {
  return typeof thing === 'number';
}

isObject

Source:

function isObject(thing) {
  return typeof thing === 'object' &&
      thing !== null && !Array.isArray(thing);
}

isRegExp

Any → Boolean

Returns true is the argument is a regular expression object.

Example:

isRegExp(/a+/) === true
isRegExp("a+") === false
isRegExp(new RegExp("a+")) === true

Source:

function isRegExp(thing) {
  return toString.call(thing) === '[object RegExp]';
}

isString

Source:

function isString(thing) {
  return typeof thing === 'string' || toString.call(thing) === '[object String]';
}

isUndefined

Source:

function isUndefined(thing) {
  return typeof thing === 'undefined';
}

typeOf

Something → String

Returns the type of the given thing as a String.

This differs from JavaScripts typeof in the way that it distinguishes null, object, and array and identifies NaN as not-a-number (Infinity and -Infinity are both reported as number). Also it knows some types native to nodash, such as list, stream, and tuple.

The possible return values are:

In ECMAScript 2015 (ES6) this function may also return symbol for Symbols.

Source:

function typeOf(thing) {
  var type = typeof thing;
  switch (type) {
    case 'number':
      return isNaN(thing) ? 'not-a-number' : 'number';
    case 'object':
      var exactType = classOf(thing);
      if (exactType === 'object' && thing.constructor && thing.constructor.__type) {
        return thing.constructor.__type;
      }
      return exactType;
    default:
      return type;
  }
}

(unclassified)

any Prelude: any

Source:

function any(p, xs) {
  for (var i = 0; i < xs.length; i++) {
    if (p(xs[i])) {
      return true;
    }
  }
  return false;
}

append ++ Prelude: ++

Source:

function append(xs, ys) {
  switch (typeOf(xs)) {
    case 'list':
      return appendList(xs, ys);
    case 'string':
      return xs + ys;
    case 'array':
      return [].concat.call(xs, ys);
    default:
      error(TypeError);
  }
}

at !!AT Prelude: !!

Source:

function at(xs, ix) {
  if (xs === undefined) {
    return xs;
  }
  return xs[ix];
}

break break_ Prelude: break

Source:

function break(p, xs) {
  var i = 0;
  while (i < xs.length && !p(xs[i])) {
    i++;
  }
  return tuple(xs.slice(0, i), xs.slice(i));
}

clone

Source:

function clone(thing) {
  if (typeof thing === 'object') {
    if (thing === null) {
      return null;
    }
    return map(clone, thing);
  }
  return thing;
}

compare Prelude: compare

Source:

function compare(a, b) {
  switch (typeof a) {
  case 'string':
    return a.localeCompare(b);
  case 'object':
    if (isFunction(a.compareTo)) {
      return a.compareTo(b);
    } else if (isArray(a)) {
      for (var i = 0; i < Math.min(a.length, b.length); i++) {
        var r = compare(a[i], b[i]);
        if (r !== 0) {
            return r;
        }
      }
      return 0;
    }
    return a.toString().localeCompare(b.toString());
  case 'number':
    return signum(a - b);
  }
  return undefined;
}

comparing

Source:

function comparing(f, a, b) {
  return compare(f(a), f(b));
}

concat Prelude: concat

Source:

function concat(xs) {
  if (isString(xs[0])) {
    return xs.join('');
  }
  var zs = [];
  var ks = Object.keys(xs);
  for (var i = 0; i < ks.length; i++) {
    [].push.apply(zs, xs[ks[i]]);
  }
  return zs;
}

concatMap Prelude: concatMap

Source:

var concatMap = /* this is a composed function */

cons : Prelude: :

Source:

function cons(x, xs) {
  switch (typeOf(xs)) {
    case 'array':
      var zs = [].slice.call(xs);
      zs.unshift(x);
      return zs;
    case 'string':
      return x + xs;
    case 'list':
      return new List(x, xs);
    case 'stream':
      return new Stream(function () {
        return tuple(x, xs);
      }); 
    default:
      error(TypeError);
  }
}

curried

Source:

function curried(fn) {
  return funcs[fn.length](fn);
}

delete delete_ Prelude: delete

Source:

function delete(x, xs) {
  var i = xs.indexOf(x);
  if (i >= 0) {
    return append(xs.slice(0,i), xs.slice(i+1));
  }
  return xs;
}

deleteBy Prelude: deleteBy

Source:

function deleteBy(p, x, xs) {
  for (var i = 0; i < xs.length; i++) {
    if (p(x, xs[i])) {
      return append(xs.slice(0,i), xs.slice(i+1));
    }
  }
  return xs;
}

difference \\ Prelude: \\

Source:

function difference(xs, ys) {
  var set = new Set();
  var i;
  for (i = 0; i < ys.length; i++) {
    set.add(ys[i]);
  }
  var zs = [];
  for (i = 0; i < xs.length; i++) {
    if (!set.has(xs[i])) {
      zs.push(xs[i]);
    }
  }
  return isString(xs) ? arrayToString(zs) : zs;
}

drop Prelude: drop

Source:

function drop(n, xs) {
  return xs.slice(n);
}

dropWhile Prelude: dropWhile

Source:

function dropWhile(p, xs) {
  var i = 0;
  while (i < xs.length && p(xs[i])) {
    i++;
  }
  return xs.slice(i);
}

either Prelude: either

Source:

function either(afun, bfun, value) {
  if (is(Left, value)) {
    return afun(value.value());
  } else if (is(Right, value)) {
    return bfun(value.value());
  } else {
    fail();
  }
}

elem Prelude: elem

Source:

function elem(x, xs) {
  for (var i = 0; i < xs.length; i++) {
    if (eq(xs[i], x)) {
      return true;
    }
  }
  return false;
}

elemIndex Prelude: elemIndex

Source:

function elemIndex(x, xs) {
  return findIndex(eq(x), xs);
}

elemIndices Prelude: elemIndices

Source:

function elemIndices(x, xs) {
  return findIndices(eq(x), xs);
}

emptyList

Source:

function emptyList() {
  return emptyList;
}

eq ==EQ Prelude: ==

Source:

function eq(a, b) {
  if (a === b) {
    return true;
  }
  var ta = typeOf(a);
  var tb = typeOf(b);
  if (ta !== tb) {
    return false;
  }
  switch (ta) {
    case 'tuple':
      return eq(a.fst(), b.fst()) && eq(a.snd(), b.snd());
    case 'list':
      return eq(a.head(), b.head()) && eq(a.tail(), b.tail());
    case 'array':
    case 'object':
      if (a.constructor !== b.constructor) {
        return false;
      }
      var k = union(Object.keys(a), Object.keys(b));
      for (var i = 0; i < k.length; i++) {
        if (!eq(a[k[i]], b[k[i]])) {
          return false;
        }
      }
      return true;
  }
  return false;
}

filter Prelude: filter

Source:

function filter(p, xs) {
  var ys;
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      ys = [];
      for (var i = 0; i < xs.length; i++) {
        if (p(xs[i])) {
          ys.push(xs[i]);
        }
      }
      return isString(xs) ? arrayToString(ys) : ys;
    default:
      ys = {};
      var ks = Object.keys(xs);
      for (var j = 0; j < ks.length; j++) {
        if (p(xs[ks[j]])) {
          ys[ks[j]] = xs[ks[j]];
        }
      }
      return ys;
  }
}

find Prelude: find

Source:

function find(p, xs) {
  for (var i = 0; i < xs.length; i++) {
    if (p(xs[i])) {
      return xs[i];
    }
  }
  return null;
}

findIndex Prelude: findIndex

Source:

function findIndex(p, xs) {
  for (var i = 0; i < xs.length; i++) {
    if (p(xs[i])) {
      return i;
    }
  }
  return null;
}

findIndices Prelude: findIndices

Source:

function findIndices(p, xs) {
  var zs = [];
  for (var i = 0; i < xs.length; i++) {
    if (p(xs[i])) {
      zs.push(i);
    }
  }
  return zs;
}

foldl1 foldl1' Prelude: foldl1'

Source:

function foldl1(f, xs) {
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      var x = xs[0];
      for (var i = 1; i < xs.length; i += 1) {
        x = f(xs[i], x);
      }
      return x;
  }
}

foldr1 Prelude: foldr1

Source:

function foldr1(f, xs) {
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      var x = xs[xs.length - 1];
      for (var i = xs.length - 2; i >= 0; i -= 1) {
        x = f(xs[i], x);
      }
      return x;
  }
}

fromLeft

Source:

function fromLeft(thing) {
  if (is(Left, thing)) {
    return thing.value();
  }
  fail();
}

fromMaybe

Source:

function fromMaybe(def, maybe) {
  if (isJust(maybe)) {
    return maybe;
  }
  return def;
}

fromRight

Source:

function fromRight(thing) {
  if (is(Right, thing)) {
    return thing.value();
  }
  fail();
}

group Prelude: group

Source:

var group = /* this is a composed function */

groupBy Prelude: groupBy

Source:

function groupBy(p, xs) {
  if (xs.length === 0) {
    return [];
  }
  var zs = [];
  var current = [xs[0]];
  var last = xs[0];
  for (var i = 1; i < xs.length; i++) {
    if (p(xs[i], last)) {
      current.push(xs[i]);
    } else {
      zs.push(current);
      current = [xs[i]];
    }
    last = xs[i];
  }
  zs.push(current);
  return isString(xs) ? map(arrayToString, zs) : zs;
}

gt >GT Prelude: >

Source:

function gt(a, b) {
  return compare(a, b) > 0;
}

gte >=GTE Prelude: >=

Source:

function gte(a, b) {
  return compare(a, b) >= 0;
}

head Prelude: head

Source:

function head(xs) {
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      return xs[0];
    case 'list':
    case 'stream':
      return xs.head();
    default:
      error(TypeError);
  }
}

indexOf

Source:

function indexOf(word, string) {
  'use strict';

  var m = 0;
  var i = 0;
  var table = [];

  var pos = 2;
  var cnd = 0;

  table[0] = -1;
  table[1] = 0;

  // build the table for KMP. This takes `O(word.length)` steps.
  while (pos < word.length) {
    if (word[pos - 1] == word[cnd]) {
      cnd = cnd + 1;
      table[pos] = cnd;
      pos = pos + 1;
    } else if (cnd > 0) {
      cnd = table[cnd];
    } else {
      table[pos] = 0;
      pos = pos + 1;
    }
  }
  
  // scan the string. This takes `O(string.length)` steps.
  while (m + i < string.length) {
    if (word[i] == string[m + i]) {
      if (i == word.length - 1) {
        return m;
      }
      i = i + 1;
    } else {
      if (table[i] > -1) {
        m = m + i - table[i];
        i = table[i];
      } else {
        i = 0;
        m = m + 1;
      }
    }
  }
  // Returns -1 if the subsequence was not found in the sequence.
  return -1;
}

init Prelude: init

Source:

function init(xs) {
  if (isString(xs)) {
    return xs.slice(0, xs.length - 1);
  }
  return [].slice.call(xs, 0, xs.length - 1);
}

inits Prelude: inits

Source:

function inits(xs) {
  var result, current, i, length;
  if (isArray(xs)) {
    result = [[]];
    current = [];
    length = xs.length;
    for (i = 0; i < length; i += 1) {
      current = current.concat(xs[i]);
      result.push(current);
    }
    return result;
  }
  // TODO the assumption is it's a string now
  result = [''];
  current = '';
  length = xs.length;
  for (i = 0; i < length; i += 1) {
    current += xs[i];
    result.push(current);
  }
  return result;
}

insert Prelude: insert

Source:

var insert = /* this is a composed function */

insertBy Prelude: insertBy

Source:

function insertBy(f, x, xs) {
  for (var i = 0; i < xs.length; i++) {
    if (f(x, xs[i]) <= 0) {
      return concat([xs.slice(0,i), x, xs.slice(i)]);
    }
  }
  return append(xs, x);
}

intercalate Prelude: intercalate

Source:

function intercalate(x, xs) {
  return concat(intersperse(x, xs));
}

intersect Prelude: intersect

Source:

function intersect(xs, ys) {
  var set = new Set();
  var zs = [];
  var i;
  for (i = 0; i < ys.length; i++) {
    set.add(ys[i]);
  }
  for (i = 0; i < xs.length; i++) {
    if (set.has(xs[i])) {
      zs.push(xs[i]);
    }
  }
  return zs;
}

intersperse Prelude: intersperse

Source:

function intersperse(x, xs) {
  if (xs.length === 0) {
    return [];
  }
  var z = [xs[0]];
  for (var i = 1; i < xs.length; i++) {
    z.push(x);
    z.push(xs[i]);
  }
  return z;
}

last Prelude: last

Source:

function last(xs) {
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      return xs[xs.length - 1];
    case 'list':
      if (xs.isEmpty()) {
        return undefined;
      }
      for (var ts = xs.tail(); !ts.isEmpty();) {
          xs = xs.tail();
          ts = xs.tail();
      }
      return xs.head();
    default:
      error(TypeError);
  }
}

length Prelude: length

Source:

function length(xs) {
  switch (typeOf(xs)) {
    case 'array':
    case 'string':
      return xs.length;
    case 'list':
      var count = 0;
      while (!xs.isEmpty()) {
        count += 1;
        xs = xs.tail();
      }
      return count;
    case 'stream':
      return Infinity;
    case 'object':
      return Object.keys(xs).length;
    default:
      error(TypeError);
  }
}

listToMaybe

Source:

function listToMaybe(xs) {
  if (is(List, xs)) {
    return xs.isEmpty() ? null : xs.head();
  }
  throw new TypeError();
}

lookup Prelude: lookup

Source:

function lookup(x, xs) {
  if (isArray(xs)) {
    for (var i = 0; i < xs.length; i++) {
      if (xs[i] && eq(xs[i][0], x)) {
        return xs[i][1];
      }
    }
  }
  return xs[x];
}

lt <LT Prelude: <

Source:

function lt(a, b) {
  return compare(a, b) < 0;
}

lte <=LTE Prelude: <=

Source:

function lte(a, b) {
  return compare(a, b) <= 0;
}

map fmap Prelude: fmap

Source:

function map(f, xs) {
  var i, ys;
  switch (typeOf(xs)) {
    case 'array':
      return mapArray(f, xs);
    case 'string':
      return arrayToString(mapArray(f, xs));
    case 'list':
      if (xs.isEmpty()) {
        return xs;
      }
    /* falls through */
    case 'stream':
      return new List(lazy(function () {
        return f(xs.head());
      }), lazy(function () {
        return map(f, xs.tail());
      }));
    case 'object':
      ys = {};
      var ks = Object.keys(xs);
      for (var j = 0; j < ks.length; j += 1) {
        ys[ks[j]] = f(xs[ks[j]], ks[j]);
      }
      return ys;
  }
}

max Prelude: max

Source:

function max(a, b) {
  return compare(a, b) > 0 ? a : b;
}

maximum Prelude: maximum

Source:

var maximum = /* this is a composed function */

maximumBy Prelude: maximumBy

Source:

function maximumBy(f, xs) {
  return foldl1(function (a, b) {
    if (f(a, b) > 0) {
      return a;
    }
    return b;
  }, xs);
}

min Prelude: min

Source:

function min(a, b) {
  return compare(a, b) < 0 ? a : b;
}

minimum Prelude: minimum

Source:

var minimum = /* this is a composed function */

minimumBy Prelude: minimumBy

Source:

function minimumBy(f, xs) {
  return foldl1(function (a, b) {
    if (f(a, b) < 0) {
      return a;
    }
    return b;
  }, xs);
}

neq /=!=<>NEQ Prelude: /=

Source:

function neq(a, b) {
  return !eq(a, b);
}

notElem Prelude: notElem

Source:

function notElem(x, xs) {
  for (var i = 0; i < xs.length; i++) {
    if (eq(xs[i], x)) {
      return false;
    }
  }
  return true;
}

nub Prelude: nub

Source:

function nub(xs) {
  var set = new Set();
  var zs = [];
  for (var i = 0; i < xs.length; i++) {
    if (!set.has(xs[i])) {
      zs.push(xs[i]);
      set.add(xs[i]);
    }
  }
  return zs;
}

or Prelude: or

Source:

var or = /* this is a composed function */

partition Prelude: partition

Source:

function _partition(p, xs) {
  var as = [];
  var bs = [];
  for (var i = 0; i < xs.length; i++) {
    (p(xs[i]) ? as : bs).push(xs[i]);
  }
  if (isString(xs)) {
    return tuple(arrayToString(as), arrayToString(bs));
  }
  return tuple(as, bs);
}

product Prelude: product

Source:

var product = /* this is a composed function */

replicate Prelude: replicate

Source:

function replicate(n, x) {
  var xs = [];
  for (var i = 0; i < n; i++) {
    xs.push(x);
  }
  return xs;
}

reverse Prelude: reverse

Source:

function reverse(xs) {
  var zs = isString(xs) ? ''.split.call(xs, '') : [].slice.call(xs);
  zs.reverse();
  return isString(xs) ? zs.join('') : zs;
}

scanl Prelude: scanl

Source:

function scanl(f, x, xs) {
  var zs = [x];
  for (var i = 0; i < xs.length; i++) {
    x = f(x, xs[i]);
    zs.push(x);
  }
  return zs;
}

scanl1 Prelude: scanl1

Source:

function scanl1(f, xs) {
  var x = xs[0];
  var zs = [x];
  for (var i = 1; i < xs.length; i++) {
    x = f(x, xs[i]);
    zs.push(x);
  }
  return zs;
}

scanr Prelude: scanr

Source:

function scanr(f, x, xs) {
  var zs = [x];
  for (var i = xs.length - 1; i >= 0; i--) {
    x = f(xs[i], x);
    zs.unshift(x);
  }
  return zs;
}

scanr1 Prelude: scanr1

Source:

function scanr1(f, xs) {
  var x = xs[xs.length - 1];
  var zs = [x];
  for (var i = xs.length - 2; i >= 0; i--) {
    x = f(xs[i], x);
    zs.unshift(x);
  }
  return zs;
}

select

Source:

function select(path, object) {
  return foldl(at, object, path.split(/\./));
}

sinh Prelude: sinh

Source:

function sinh(x) {
  return (Math.exp(x) - Math.exp(-x)) / 2;
}

sort Prelude: sort

Source:

function sort(xs) {
  if (xs.length <= 1) {
    return xs;
  }
  var zs = isString(xs) ? ''.split.call(xs, '') : [].slice.call(xs);
  if (isNumber(zs[0])) {
    zs.sort(function (a, b) { return a - b; });
  } else if (isString(zs[0])) {
    zs.sort(function (a, b) { return a.localeCompare(b); });
  } else {
    zs.sort(compare);
  }
  return isString(xs) ? zs.join('') : zs;
}

sortBy Prelude: sortBy

Source:

function sortBy(fn, xs) {
  if (xs.length <= 1) {
    return xs;
  }
  var yesItsAString = isString(xs);
  var zs = yesItsAString ? ''.split.call(xs, '') : [].slice.call(xs);
  zs.sort(fn);
  return yesItsAString ? zs.join('') : zs;
}

span Prelude: span

Source:

function span(p, xs) {
  var i = 0;
  while (i < xs.length && p(xs[i])) {
      i++;
  }
  return tuple(xs.slice(0, i), xs.slice(i));
}

splitAt Prelude: splitAt

Source:

function splitAt(n, xs) {
  return tuple(take(n, xs), drop(n, xs));
}

tail Prelude: tail

Source:

function tail(xs) {
  switch (typeOf(xs)) {
    case 'array':
      return [].slice.call(xs, 1);
    case 'string':
      return "".slice.call(xs, 1);
    case 'list':
    case 'stream':
      return xs.tail();
    default:
      error(TypeError);
  }
}

tails Prelude: tails

Source:

function tails(xs) {
  var result, current, i;
  if (isArray(xs)) {
    result = [[]];
    current = [];
    for (i = xs.length - 1; i >= 0; i -= 1) {
      current = [xs[i]].concat(current);
      result.unshift(current);
    }
    return result;
  }
  // TODO the assumption is it's a string now
  result = [''];
  current = '';
  for (i = xs.length - 1; i >= 0; i -= 1) {
    current = xs[i] + current;
    result.unshift(current);
  }
  return result;
}

take Prelude: take

Source:

function take(n, xs) {
  switch (typeOf(xs)) {
    case 'string':
      return "".slice.call(xs, 0, n);
    case 'array':
      return [].slice.call(xs, 0, n);
    case 'list':
    case 'stream':
      return takeGenerator(n, xs);
    default:
      error(TypeError);
  }
}

takeWhile Prelude: takeWhile

Source:

function takeWhile(p, xs) {
  var i = 0;
  while (i < xs.length && p(xs[i])) {
    i++;
  }
  return xs.slice(0, i);
}

transpose Prelude: transpose

Source:

function transpose(xss) {
  if (!isArray(xss)) {
    var zss = {};
    var ks = Object.keys(xss);
    for (var k = 0; k < ks.length; k++) {
      zss[xss[ks[k]]] = ks[k];
    }
    return zss;
  }
  var j = 0;
  var zs = [];
  var current;
  do {
    current = [];
    for (var i = 0; i < xss.length; i++) {
      if (xss[i][j] !== undefined) {
        current.push(xss[i][j]);
      }
    }
    j += 1;
  } while (current.length > 0 && zs.push(current));
  if (isString(xss[0])) {
    zs = map(arrayToString, zs);
  }
  return zs;
}

union Prelude: union

Source:

function union(xs, ys) {
  var set = new Set();
  var zs = [];
  var i;
  for (i = 0; i < xs.length; i++) {
    zs.push(xs[i]);
    set.add(xs[i]);
  }
  for (i = 0; i < ys.length; i++) {
    if (!set.has(ys[i])) {
      zs.push(ys[i]);
    }
  }
  return zs;
}

Appendix

Coverage of Haskell Prelude

Prelude functions supported in Nodash

Prelude functions missing from Nodash

Nodash-specific additions

Fork me on GitHub