Home

Awesome

maryamyriameliamurphies.js

License Build Status Test Coverage Downloads Monads

NPM

Learn functional programming in ES2015 JavaScript from the principles and code patterns of Haskell

Make your own code more functional by using this library as it is or just implementing its ideas yourself

Now in version 1.0

All told, a monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor. — Saunders Mac Lane, Categories for the Working Mathematician

In general, an arrow type will be a parameterised type with two parameters, supporting operations analogous to return and >>=. Just as we think of a monadic type m a as representing a 'computation delivering an a', so we think of an arrow type a b c (that is, the application of the parameterised type a to the two parameters b and c) as representing a 'computation with input of type b delivering a c'. — John Hughes, Generalising monads to arrows

In mathematics, a functor is a type of mapping between categories which is applied in category theory. Functors can be thought of as homomorphisms between categories. In the category of small categories, functors can be thought of more generally as morphisms. — Wikipedia, Functor

murphy come, murphy go, murphy plant, murphy grow, a maryamyriameliamurphies, in the lazily eye of his lapis — James Joyce, Finnegans Wake

About

maryamyriameliamurphies.js is a library of Haskell-style morphisms implemented in JavaScript using ECMAScript 2015 syntax. That is, it's a collection of pure functions designed to showcase in a more widely-used language than Haskell the ways and means of functional programming, for which the newest dialect of JavaScript has improved support. If you're interested in functional programming or even Haskell itself, but find that world intimidating, this library may be a useful conceptual bridge. The syntax I use will probably come across as unconventional, as it mirrors as closely as possible the terse, efficient style of Haskell. Eventually, however, you may find it easy enough to reason about, thanks to its relative lack of side effects and foundation in function composition. If you're curious about strange-sounding things like functors, monads, partial application, currying, and lazy evaluation, then there's something here for you.

First published entirely by chance on St. Patrick's Day, 2016.

Try it now with Tonic
Complete Online API Documentation

How to install

How to use with npm if you clone

These commands require that you have certain npm packages installed. See below.

How to test in the browser

const m = require('maryamyriameliamurphies'); // yes, I know it's too long

const hello = str => { return m.print(`Hello ${str}!`), m.just(str); }

const str = m.just(`world`);

const sayHello = () => {
  m.Do(str)
   .flatMap(hello)
   .inject(`monad`)
   .flatMap(hello);
}

sayHello();

// "Hello world!"
// "Hello monad!"

Your mileage may vary, depending on which browser you use to test. This example works in the latest version of Chrome, but ES2015 syntax is not fully supported in Safari as of this writing.

Description

Since the average explanation of functional programming terminology makes about as much sense to the average reader as the average page of Finnegans Wake, I gave this library a whimsical, literary name. Also, I'm an English literature Ph.D. student, and functional code strikes me as poetic (as "composed" in multiple senses) even though the technical explanations are impenetrably obtuse. All you need to know—in fact, all I understand—is that a pure function (or a morphism in general) simply describes how one thing can predictably transform into another. So a functional program, much like Joyce's final work, is an extended description of how things change.

These functions are experimental, as Haskell's type system translates only awkwardly to a JavaScript idiom, but I'd be delighted if any of them turn out to be useful. I tried hard to make them as pure as possible, which is why most (but not all) of them accept as arguments and return as values single values, and very few are defined as methods on prototypes. I also followed Haskell code patterns as closely as I could for each implementation (as much as it made sense to do so), resulting in a style that is sometimes extremely straightforward and sometimes bewilderingly terse.

There are two Haskell concepts that I use in the code that do not perfectly fit into the JavaScript way of doing things: the type class and the data type. In Haskell, a type class is similar to a protocol or trait in other programming languages. It describes an interface that objects conforming to it must implement.

A type class is a way of making fully parameterized types more useful by placing constraints on them. For example, the Eq type class in this library provides functionality for comparing whether the objects that implement it are equal. Objects that provide their own isEq() function will perform this test and return a boolean. Note that Haskell type classes are in no way comparable to "classes" in OOP.

A data type, on the other hand, is much closer to an OO class definition, as it does describe a custom type. The Tuple type is an example of a data type, as it represents a container for other, more basic values. As is often the case with objects in classical languages, instances of Haskell data types are created with special constructor functions that initialize them based on the arguments to those functions. A data type does not inherit (in the usual way) from other data types, however. Instead, it describes how constructor functions convert values passed in as arguments to those functions into the values that comprise that particular type.

As mentioned above, data types can be constrained (or not) by type classes, so as to provide additional functionality—Eq is an example of this, as is Ord, a type class that allows objects to be compared (greater than, less than, etc.). Tuple implements both of these type classes, as one may rightly want to compare tuples or test them for equality, for example.

Since JavaScript is not a strongly typed language by nature, it seemed unnecessary to me (and, for better or worse, antithetical to the JS spirit) to recreate the entirety of Haskell's static type system, though I do provide a limited amount of type checking. Anyone interested in better type safety should probably be using something like PureScript or GHCJS. Instead, I use the new ES2015 class pattern for data types with static methods defined on those classes to provide the functionality of type classes. Since the classes and their constructors are not exposed in the API this library provides, instances of data types must be created using specialized functions provided for this purpose. This keeps the static "type class" methods private and affords some degree of namespace protection for the data types.

ES2015 specifies tail call optimization, which will ensure that all the nifty Haskell-esque recursions this library uses won't blow up your call stack (when it's actually implemented).

See also

Development

Requires:

Babel packages and plugins:

What the name of this library means

The word "maryamyriameliamurphies" occurs on pg. 293 of James Joyce's Finnegans Wake. The two brothers Kev and Dolph (surrogates for the archetypal Shem and Shaun, who represent all rival brothers in history and myth) are having a math lesson. Dolph, the elder, is attempting to explain to Kev the first postulate of Euclid, which results in a rather prurient diagram of circles and triangles. Happily for me, as a functional programmer, it contains a λ. If you want to find out about the naughtier significances of this diagram, you'll have to research that for yourself (hint: like functional programming, it involves "lifting"). In the middle of Dolph's explanation, Kev starts to daydream, hence all the invocations of "murphy," an allusion to Morpheus, the Greek god of dreams (also the common Irish surname, Murphy, as well as a slang word meaning both "potato" and "confidence game").

Here's my own interpretation of maryamyriameliamurphies:

maryamyriameliamurphies — Wow, a whole bunch of sweet functions!

API

See the online documentation for more extensive explanations and examples. The online docs can also be generated locally with JSDoc if you git clone or npm install this repo.

Basic functions

See Haskell Data.Function and Prelude.

Eq

See Haskell Eq.

Ord

See Haskell Ord.

Monoid

See Haskell Monoid.

Functor

See Haskell Functor.

Applicative

See Haskell Applicative.

Monad

See Haskell Monad.

Foldable

See Haskell Foldable.

Traversable

See Haskell Traversable.

Maybe

See Haskell Maybe.

Tuple

See Haskell Tuple.

List

See Haskell List.

Basic functions

List transformations

Reducing lists

Special folds

Building lists

Infinite lists

Sublists

Searching

Indexing

Zipping and unzipping lists

"Set" operations

Ordered lists

Utility functions