如何更改模板字符串外推的值
How to change the value that a template string extrapolates
我正在尝试编写一个简单的 Id monad 来尝试和学习。
这是我写的:
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}
returns 嵌套 Id
monad 的正确字符串?
您需要覆盖 toString
,而不是 valueOf
。与字符串连接(或插入模板字符串)会将值强制转换为字符串,并且您的对象继承 Object.prototype.toString
which returns [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;
我正在尝试编写一个简单的 Id monad 来尝试和学习。
这是我写的:
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}
returns 嵌套 Id
monad 的正确字符串?
您需要覆盖 toString
,而不是 valueOf
。与字符串连接(或插入模板字符串)会将值强制转换为字符串,并且您的对象继承 Object.prototype.toString
which returns [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;