Ramda Adjunct 5.1.0

lensIso.js

  1. import { curry, map } from 'ramda';
  2. // This implementation was highly inspired by the implementations
  3. // in ramda-lens library.
  4. //
  5. // https://github.com/ramda/ramda-lens
  6. // isomorphic :: ((a -> b), (b -> a)) -> Isomorphism
  7. // Isomorphism = x -> y
  8. const isomorphic = (to, from) => {
  9. const isomorphism = (x) => to(x);
  10. isomorphism.from = from;
  11. return isomorphism;
  12. };
  13. // isomorphisms :: ((a -> b), (b -> a)) -> (a -> b)
  14. const isomorphisms = (to, from) =>
  15. isomorphic(
  16. curry((toFunctorFn, target) => map(from, toFunctorFn(to(target)))),
  17. curry((toFunctorFn, target) => map(to, toFunctorFn(from(target))))
  18. );
  19. // from :: Isomorphism -> a -> b
  20. const from = curry((isomorphism, x) => isomorphism.from(x));
  21. /**
  22. * Defines an isomorphism that will work like a lens. It takes two functions.
  23. * The function that converts and the function that recovers.
  24. *
  25. * @func lensIso
  26. * @memberOf RA
  27. * @since {@link https://char0n.github.io/ramda-adjunct/1.19.0|1.19.0}
  28. * @category Relation
  29. * @typedef Lens s a = Functor f => (a -> f a) -> s -> f s
  30. * @sig (s -> a) -> (a -> s) -> Lens s a
  31. * @param {!function} to The function that converts
  32. * @param {!function} from The function that recovers
  33. * @return {!function} The isomorphic lens
  34. * @see {@link http://ramdajs.com/docs/#lens|R.lens}
  35. *
  36. * @example
  37. *
  38. * const lensJSON = RA.lensIso(JSON.parse, JSON.stringify);
  39. *
  40. * R.over(lensJSON, assoc('b', 2), '{"a":1}'); //=> '{"a":1,"b":2}'
  41. * R.over(RA.lensIso.from(lensJSON), R.replace('}', ',"b":2}'), { a: 1 }); // => { a: 1, b: 2 }
  42. */
  43. const lensIso = curry(isomorphisms);
  44. lensIso.from = from;
  45. export default lensIso;