Как создать чисто функциональную специальную полиморфную линзу без какого-либо самоанализа? - PullRequest
0 голосов
/ 02 декабря 2018

Я адаптировал реализацию объектива DrBoolean , чтобы она работала без самоанализа / печати утки / опознавания прототипа.Вычисления должны определяться исключительно продолжениями и аргументами функций функций более высокого порядка.Я зашел так далеко:

const id = x => x;

// compose n functions (right to left)
const $$ = (f, ...fs) => x =>
  fs.length === 0
    ? f(x)
    : f($$(...fs) (x));

// function encoded Const type
const Const = x => k => k(x);
const constMap = f => fx => fx(x => Const(x));
const runConst = fx => fx(id);

// lens constructor
const objLens = k => cons => o =>
  constMap(v => Object.assign({}, o, {[k]: v})) (cons(o[k]));

const arrLens = i => cons => xs =>
  constMap(v => Object.assign([], xs, {[i]: v})) (cons(xs[i]));

const view = fx =>
  $$(runConst, fx(Const));

const user = {name: "Bob", addresses: [
  {street: '99 Maple', zip: 94004, type: 'home'},
  {street: '2000 Sunset Blvd', zip: 90069, type: 'work'}]};

// a lens
const sndStreetLens =
  $$(objLens("addresses"), arrLens(1), objLens("street"));

console.log(
  view(sndStreetLens) (user) // 2000 Sunset Blvd
);

В этой версии ограничение функтора constMap жестко закодировано в конструкторе линзы.Когда view вызывает линзу, правильный тип ($$(runConst, fx(Const))) уже пройден, но для того, чтобы получить специальную полиморфную линзу, мне нужно также передать соответствующий экземпляр функтора.

Я ужепопробовал самую очевидную вещь $$(runConst, fx(constMap) (Const)), однако это мешает композиции.Я просто не могу понять это.

...