focused
Version:
Lens/Optics library for JavaScript
83 lines (68 loc) • 2.68 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.has = exports.preview = exports.toList = exports.set = exports.over = exports.view = undefined;
exports.compose2 = compose2;
exports.compose = compose;
var _utils = require("./utils");
var _typeClasses = require("./typeClasses");
var _iso = require("./iso");
var _prism = require("./prism");
/*
type Settable<S,T,A,B> = (Identity, A => Identity<B>, S) => Identity<T>
type Getting<R,S,A> = (Const<R>, A => Const<R,A>, S) => Const<R,S>
type Getter<S,A> = <R>Getting<R,S,A> -- ie should work for any R
*/
// view : Getting<A,S,A> => S => A
const view = exports.view = (0, _utils.curry2)(function _view(aGetter, s) {
return aGetter(_typeClasses.ConstVoid, _utils.id, s);
});
function _over(aSettable, f, s) {
return aSettable(_typeClasses.Identity, f, s);
}
// over : Settable<S,T,A,B> => (A => B) => S => T
const over = exports.over = (0, _utils.curry3)(_over);
// set : Settable<S,T,A,B> => B => S => T
const set = exports.set = (0, _utils.curry3)(function _set(aSettable, v, s) {
return _over(aSettable, (0, _utils.konst)(v), s);
});
// toList : Getting<[A], S,A> => S => [A]
const toList = exports.toList = (0, _utils.curry2)(function toList(aGetting, s) {
return aGetting(_typeClasses.ConstList, _typeClasses.List.pure, s);
});
// preview : Getting<A | null, S,A> => S => (A | null)
const preview = exports.preview = (0, _utils.curry2)(function _preview(aGetting, s) {
return aGetting(_typeClasses.ConstFirst, _utils.id, s);
});
// has : (Getting<Boolean, S,A>, S) => Boolean
const has = exports.has = (0, _utils.curry2)(function _has(aGetting, s) {
return aGetting(_typeClasses.ConstAny, (0, _utils.konst)(true), s);
});
/**
* Compose 2 optics, Abstarcting the constraints, the type can be seen as
*
* compose2 : (Optic<S,T,A,B>, Optic<A,B,X,Y>) => Optic<S,T,A,B>
*
* However, we need also to combine 2 Isos into an Iso and idem for Prisms
* In Haskell this is acheived using type classes & Profunctors
*
* Here we're just inspecting types at runtime, it's ugly and less flexible but
* works for our limited cases. Most notably, I don't want to introduce Profunctors
* for performance reasons.
*/
function compose2(parent, child) {
// ad-hoc polymporphism FTW
if (parent.__IS_ISO && child.__IS_ISO) {
return (0, _iso.compose2Isos)(parent, child);
}
if (parent.__IS_PRISM && child.__IS_PRISM) {
return (0, _prism.compose2Prisms)(parent, child);
}
return function composedOptics(F, f, s) {
return parent(F, a => child(F, f, a), s);
};
}
function compose(...ls) {
return ls.reduce(compose2);
}