Skip to content

Commit

Permalink
feat: Update function names and parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
edahlseng committed Jul 18, 2019
1 parent c9b0c06 commit 104c4e8
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 46 deletions.
55 changes: 35 additions & 20 deletions sources/eff.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* @flow */

import { always, pipe, equals, F } from "ramda";
import { always, pipe, equals as equalsGeneric, F } from "ramda";
import { taggedSum } from "daggy";

// value :: any
Expand All @@ -11,39 +11,60 @@ const Eff = taggedSum("Eff", {
Impure: ["effect", "continuation"],
});

Eff.prototype.map = function(f) {
return this.chain(a => Eff.of(f(a)));
};
type Pure = { cata: Function };
type Impure = { cata: Function };
type EffMonad = Pure | Impure;

export const pure = Eff.Pure;

export const of = pure;

export const impure = (continuation: Function) => (effect: EffMonad) =>
Eff.Impure(effect, continuation);

export const send = (effect: any) => Eff.Impure(effect, Eff.Pure);

const pipeK = (a, b) => c => a(c).chain(b);

// -----------------------------------------------------------------------------
// Equals
// -----------------------------------------------------------------------------

Eff.equals = (a, b) =>
export const map = (f: Function) => (eff: EffMonad) =>
chain(a => pure(f(a)))(eff);

Eff.prototype.map = function(f) {
return map(f)(this);
};

// -----------------------------------------------------------------------------
// Equals
// -----------------------------------------------------------------------------

export const equals = (a: EffMonad) => (b: EffMonad) =>
a.cata({
Pure: b.cata({
Pure: equals,
Pure: equalsGeneric,
Impure: always(F),
}),
Impure: (aEffect, aContinuation) =>
b.cata({
Pure: F,
Impure: (bEffect, bContinuation) =>
equals(aEffect, bEffect) && equals(aContinuation, bContinuation),
equalsGeneric(aEffect, bEffect) &&
equalsGeneric(aContinuation, bContinuation),
}),
});

Eff.prototype.equals = function(b) {
return Eff.equals(this, b);
return equals(this)(b);
};

// -----------------------------------------------------------------------------
// Chain
// -----------------------------------------------------------------------------

Eff.chain = (eff, nextContinuation) =>
export const chain = (nextContinuation: Function) => (eff: EffMonad) =>
eff.cata({
Pure: x => nextContinuation(x),
Impure: (effect, continuation) =>
Expand All @@ -56,17 +77,13 @@ Eff.chain = (eff, nextContinuation) =>
),
});

Eff.prototype.chain = function chain(nextContinuation) {
return Eff.chain(this, nextContinuation);
Eff.prototype.chain = function(nextContinuation) {
return chain(nextContinuation)(this);
};

Eff.of = Eff.Pure;

export default Eff;

type Pure = { cata: Function };
type Impure = { cata: Function };
type EffMonad = Pure | Impure;
// -----------------------------------------------------------------------------
// Interpreting and Running
// -----------------------------------------------------------------------------

export const run = (...interpreters: Array<Function>) => (
callback: Function,
Expand All @@ -88,8 +105,6 @@ export const run = (...interpreters: Array<Function>) => (
}),
)(effectfulMonad);

export const send = (t: any) => Eff.Impure(t, Eff.Pure);

export const interpreter = ({
predicate,
handler,
Expand Down
41 changes: 16 additions & 25 deletions sources/eff.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import test from "ava";
import jsverify from "jsverify";
import { pipe } from "ramda";

import Eff, { send } from "./eff";
import { chain, equals, pure, send } from "./eff";

// Note: JSVerify does not appear to have a way to generate arbitrary arbitraries;
// this means that each arbitrary in JSVerify has to be of a certain type.
Expand All @@ -22,10 +22,7 @@ test("Reflexivity (Pure)", t => {
// equals a a ≡ true

jsverify.assert(
jsverify.forall(
"number",
a => Eff.equals(Eff.Pure(a), Eff.Pure(a)) === true,
),
jsverify.forall("number", a => equals(pure(a))(pure(a)) === true),
);
t.pass();
});
Expand All @@ -36,7 +33,7 @@ test("Reflexivity (Impure)", t => {
jsverify.assert(
jsverify.forall(
"json",
effect => Eff.equals(send(effect), send(effect)) === true,
effect => equals(send(effect))(send(effect)) === true,
),
);
t.pass();
Expand All @@ -49,9 +46,7 @@ test("Symmetry (Pure)", t => {
jsverify.forall(
"number",
"number",
(a, b) =>
Eff.equals(Eff.Pure(a), Eff.Pure(b)) ===
Eff.equals(Eff.Pure(b), Eff.Pure(a)),
(a, b) => equals(pure(a))(pure(b)) === equals(pure(b))(pure(a)),
),
);
t.pass();
Expand All @@ -64,7 +59,7 @@ test("Symmetry (Impure)", t => {
jsverify.forall(
"json",
"json",
(a, b) => Eff.equals(send(a), send(b)) === Eff.equals(send(b), send(a)),
(a, b) => equals(send(a))(send(b)) === equals(send(b))(send(a)),
),
);
t.pass();
Expand All @@ -76,9 +71,8 @@ test("Transitivity (Pure)", t => {

jsverify.assert(
jsverify.forall("number", "number", "number", (a, b, c) =>
Eff.equals(Eff.Pure(a), Eff.Pure(b)) &&
Eff.equals(Eff.Pure(b), Eff.Pure(c))
? Eff.equals(Eff.Pure(a), Eff.Pure(b))
equals(pure(a))(pure(b)) && equals(pure(b))(pure(c))
? equals(pure(a))(pure(b))
: true,
),
);
Expand All @@ -90,8 +84,8 @@ test("Transitivity (Impure)", t => {

jsverify.assert(
jsverify.forall("json", "json", "json", (a, b, c) =>
Eff.equals(send(a), send(b)) && Eff.equals(send(b), send(c))
? Eff.equals(send(a), send(b))
equals(send(a))(send(b)) && equals(send(b))(send(c))
? equals(send(a))(send(b))
: true,
),
);
Expand Down Expand Up @@ -133,10 +127,10 @@ test("Left Identity", t => {
jsverify.forall("number", "number -> number", (a, f) => {
const f2 = pipe(
f,
Eff.Pure,
pure,
);

return Eff.equals(Eff.chain(Eff.Pure(a), f2), f2(a));
return equals(chain(f2)(pure(a)))(f2(a));
}),
);
t.pass();
Expand All @@ -146,9 +140,7 @@ test("Right Identity", t => {
// return m >>= return ≡ m

jsverify.assert(
jsverify.forall("number", a =>
Eff.equals(Eff.chain(Eff.Pure(a), Eff.Pure), Eff.Pure(a)),
),
jsverify.forall("number", a => equals(chain(pure)(pure(a)))(pure(a))),
);
t.pass();
});
Expand All @@ -164,17 +156,16 @@ test("Associativity", t => {
(a, f, g) => {
const f2 = pipe(
f,
Eff.Pure,
pure,
);

const g2 = pipe(
g,
Eff.Pure,
pure,
);

return Eff.equals(
Eff.chain(Eff.chain(Eff.Pure(a), f2), g2),
Eff.chain(Eff.Pure(a), x => Eff.chain(f2(x), g2)),
return equals(chain(g2)(chain(f2)(pure(a))))(
chain(x => chain(g2)(f2(x)))(pure(a)),
);
},
),
Expand Down
1 change: 0 additions & 1 deletion sources/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* @flow */

export * from "./eff.js";
export { default as Eff } from "./eff.js";

import * as FileSystem from "./fileSystem.js";
export { FileSystem };
Expand Down

0 comments on commit 104c4e8

Please sign in to comment.