focused
Version:
Lens/Optics library for JavaScript
82 lines (72 loc) • 2.25 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.left = left;
exports.right = right;
exports.prism = prism;
exports.simplePrism = simplePrism;
exports.withPrism = withPrism;
exports.compose2Prisms = compose2Prisms;
/*
type Either<T,A> = { type: "LEFT", value: T } | { type: "RIGHT", value: A }
type Prism<S,T,A,B> =
(Applicative<F>, A => F<B>, S) => F<T>
& { __IS_PRISM: true, match: S => Either<T,A>, to: B => T }
type SimplePrism<S,A> = Prism<S,S,A,A>
*/
function left(value) {
return { type: "LEFT", value };
}
function right(value) {
return { type: "RIGHT", value };
}
// prism : (S => Either<T,A>, B => T) => Prism<S,T,A,B>
function prism(match, build) {
function prismFn(anApplicative, f, s) {
const result = match(s);
if (result.type === "LEFT") return anApplicative.pure(result.value);
const fa = f(result.value);
return anApplicative.map(build, fa);
}
// escape hatch to avoid profunctors
Object.assign(prismFn, {
__IS_PRISM: true,
build,
match
});
return prismFn;
}
// simplePrism : (S => Maybe<A>, A => S) => SimplePrism<S,A>
function simplePrism(match, build) {
return prism(s => {
const result = match(s);
return result === null ? { type: "LEFT", value: s } : { type: "RIGHT", value: result };
}, build);
}
// withPrism : (Prism<S,T,A,B>, (S => Either<T,A>, B => T) => R) => R
function withPrism(aPrism, f) {
return f(aPrism.match, aPrism.build);
}
// parent : Prism<S,T,A,B> & { match: S => Either<T,A>, to: B => T }
// child : Prism<A,B,X,Y> & { match: A => Either<B,X>, to: Y => B }
// return : Prism<S,T,X,Y> & { match: S => Either<T,X>, to: Y => T }
function compose2Prisms(parentL, childL) {
const { match: sta, build: bt } = parentL;
const { match: abx, build: yb } = childL;
return prism(s => {
const ta = sta(s);
if (ta.type === "LEFT") return ta;
const bx = abx(ta.value);
if (bx.type === "RIGHT") return bx;
return bt(bx.value);
}, y => bt(yb(y)));
}
// json : SimplePrism<String,Object>
const maybeJson = exports.maybeJson = simplePrism(s => {
try {
return JSON.parse(s);
} catch (e) {
return null;
}
}, JSON.stringify);