Skip to content

Function arrows and a template tag for arrows and function combinators

License

Notifications You must be signed in to change notification settings

1Computer1/arrow-tag

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

arrow-tag

Function arrows and a template tag for arrows and function combinators.

The design philosophy of this library (other than being a proof-of-concept) is to give programmers a way to compose their functions without having to resort to a messy nesting of combinators nor having to mess with their functions through a middleman e.g. currying.

This library is based mostly upon Haskell's Control.Arrow and Data.Function, and functional programming in general, with liberties taken to ease its use in JavaScript.

Example

With arrow-tag language and template tag:

const { arrow, operators: { add, pow, rsect } } = require('arrowtag');

// Read this as "add on (** 2) then square root".
// That is, `(x, y) => Math.sqrt(x ** 2 + y ** 2)`.
const pythag = arrow`${add} <^> ${rsect(pow, 2)} >>> ${Math.sqrt}`;

pythag(3, 4); // -> 5

Equivalent function calls:

const { on, composeLR, operators: { add, pow, rsect } } = require('arrowtag');

const pythag = composeLR(on(add, rsect(pow, 2)), Math.sqrt);

pythag(3, 4); // -> 5

Combinators

All the combinators are available as normal functions or as a part of the arrow-tag language.
Multiple inputs are the same as normal JavaScript, i.e. we treat function arguments as a single tuple.
Multiple outputs are simulated using arrays with an isTuple symbol set to true.

Unary combinators have a corresponding prefix operator.
Binary operators also have an associativity and precedence; higher precedence means tighter binding.
You can view the full list of combinators and their behavior in src/combinators.js.
Notation is fairly obvious; (...a) refers to the entire spread of types passed into the function.

Also included are aliases for JavaScript operators, e.g. add for (x, y) => x + y.
You can also create operator sections as in lsect(1, add) for x => 1 + x.

More Examples

const f = arrow`${rsect(mul, 2)} >>> ${String} >>> ${rsect(add, ' wow!')}`;
f(10); // -> "20, wow!"
const f = arrow`${rsect(pow, 2)} &&& ${Math.sqrt}`;
f(4); // -> [16, 2, [Symbol(isTuple)]: true]
const f = arrow`${sub} <^> ${x => x.age}`;
[{ age: 10 }, { age: 3 }].sort(f); // -> [{ age: 3 }, { age: 10 }]
const f = arrow`${rsect(mul, 10)} @ 2`;
f(1, 2, 3, 4); // -> [1, 2, 30, 4, [Symbol(isTuple)]: true]

About

Function arrows and a template tag for arrows and function combinators

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published