Как изменить значение, которое экстраполирует строка шаблона - PullRequest
2 голосов
/ 10 июля 2019

Я пытаюсь написать простую Id монаду, чтобы поиграть с ней и научиться.

Вот что я написал:

const util = require('util');

const Id = x => ({
  [util.inspect.custom]: () => `Id(${x})`,
  map: f => Id.of(f(x)),
  flatMap: f => f(x),
  valueOf: () => `Id(${x})`,
});

Id.of = Id;

const foo = Id.of('foo');
const toUpper = str => Id.of(str.toUpperCase());

const fooBoxed = foo.map(toUpper); // Oh oh, should be Id(Id('FOO'));
const FOO = foo.flatMap(toUpper); // Yay, Id('FOO');

console.log(fooBoxed);
console.log(FOO);

fooBoxed должен выйти из системы Id(Id(Foo)), но он выходит из системы Id([object object]). Я попытался изменить valueOf и inspect, но оба не работают. Я подозреваю, что ${x} вызывает другой метод, и я не могу найти в Интернете, что это такое. Что мне нужно изменить, чтобы ${x} возвращал правильную строку для моей вложенной Id монады?

1 Ответ

2 голосов
/ 10 июля 2019

Вы хотите перезаписать toString, а не valueOf. Конкатенация со строкой (или интерполяция строки шаблона) приведёт значение к строке, и ваши объекты наследуют Object.prototype.toString, что возвращает [object …].

const Id = x => ({
  toString: () => `Id(${x})`,
  map: f => Id.of(f(x)),
  flatMap: f => f(x),
});

Id.of = Id;

const foo = Id.of('foo');
const toUpper = str => Id.of(str.toUpperCase());

const fooBoxed = foo.map(toUpper);
const FOO = foo.flatMap(toUpper);

console.log(fooBoxed.toString()); // Yay, Id(Id('FOO'));
console.log(FOO.toString()); // Yay, Id('FOO');

Однако, поскольку вы, похоже, намереваетесь использовать это для отладки, вы должны использовать отладочное представление значения x. Для этого позвоните util.inspect() самостоятельно:

const util = require('util');

const Id = x => ({
  [util.inspect.custom]: () => `Id(${util.inspect(x)})`,
//                                   ^^^^^^^^^^^^
  map: f => Id.of(f(x)),
  flatMap: f => f(x),
  valueOf: () => x,
});
Id.of = Id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...