npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

eff

v0.4.0

Published

An extensible effect monad based on the freer monad

Downloads

5

Readme

Eff

An extensible effect monad.

CircleCI

Eff is a container for effects. It separates effects into two parts – a description of what needs to be done, and the logic to make it happen. These individual parts can be combined with other effects, creating applications that are much easier to understand, test, and maintain.

Motivation

Composition is the pinnacle of reusability for software. While easy to achieve when working with pure functions, the reality is that any useful application necessarily produces effects, and are by definition impure, making composition much more difficult. The Eff monad allows for these "impure" applications to easily utilize composition by splitting effects into two separate pieces – the definition of an effect, and the interpretation of an effect – each of which can be composed.

Documentation

Eff is available on NPM. To install:

npm install eff

To use:

import { pure, send, run, ... } from 'eff';

For an introduction to working with Eff, see the example below. A detailed API reference can be found in the documentation/ directory.

Example

This library comes with several different effects already defined, though custom effects can be easily written. This example uses the FileSystem effects to read from a file, uppercase all of its content, and then write a new file with the transformed content.

The first step is to write the application as a definition of the effects that will be performed:

import { FileSystem, run } from "eff";

const upperCase = str => str.toUpperCase();

const application =
	FileSystem.readFile("./a.txt")
	.map(upperCase)
	.chain(FileSystem.writeFile("./b.txt"));

The application as written above will not actually do anything, it's just a description of what should be done. The magic comes from interpreting this description:

import { run } from "eff";

// In the line below the application is interpreted. This is when the effects are actually run.
run([FileSystem.interpretLocalFileSystem("/home/me")])(() => console.log("Done!"))(application)

The interpreter contains two different parts:

  • FileSystem.interpretLocalFileSystem: This is the standard FileSystem effect interpreter.
  • run: This is the main Eff interpreter. It is always needed to properly interpret an Eff monad.

At first blush this separation of effects into a definition and its interpretation may seem inconsequential. Nevertheless, this approach gives us extremely powerful abilities that go beyond just separation of concerns:

  • trivial testability
  • composition of applications

Let's take a closer look at the first one, testability, in action:

let fileSystem = { "/home/me/a.txt": "hello, world" };

run([
	FileSystem.interpretMockFileSystem({
		workingDirectory: "/home/me",
		startingFileSystem: fileSystem,
		onUpdate: newFileSystem => {
			fileSystem = newFileSystem;
		}
	})
])(mockFileSystemOutput => {
	if (mockFileSystemOutput["/home/me/b.txt"] === "HELLO, WORLD") {
		console.log("Test passed!");
	} else {
		console.log("Test failed!");
	}
})(application);

We can interpret the application definition with a mock interpreter just as easily as the original interpreter. This allows us to verify the logic of the application without needing to actually interact with a live file system.

Contributing

Community contributions are welcome! See CONTRIBUTING.md for more information.

References

This library was originally based on the work presented in the following research papers:

Extensible Effects: An Alternative to Monad Transformers Oleg Kiselyov, Amr Sabry, and Cameron Swords. 2013. Extensible effects: an alternative to monad transformers. In Proceedings of the 2013 ACM SIGPLAN symposium on Haskell (Haskell '13). ACM, New York, NY, USA, 59-70. DOI=http://dx.doi.org/10.1145/2503778.2503791

Freer Monads, More Extensible Effects Oleg Kiselyov and Hiromi Ishii. 2015. Freer monads, more extensible effects. SIGPLAN Not. 50, 12 (August 2015), 94-105. DOI=http://dx.doi.org/10.1145/2887747.2804319