javascript - 民间故事/幻想世界可能没有按预期工作
问题描述
阅读Frisbys 函数式编程指南,目前在关于Maybe
. 在附录中,本书建议使用民间故事或幻想世界。
然而,这两个图书馆Maybe
似乎都不像书中描述的那样工作。
const Maybe = require('folktale/maybe')
// const Maybe = require('fantasy-options')
const {
flip, concat, toUpper, path, pathOr, match, prop
} = require('ramda')
console.log(
Maybe.of('Malkovich Malkovich').map(match(/a/ig))
)
// Just(['a', 'a'])
Maybe.of(null).map(match(/a/ig))
//******************************
// TypeError: Cannot read property 'match' of null
//******************************
// Nothing
Maybe.of(
{ name: 'Boris' }
).map(prop('age')).map(add(10))
// Nothing
Maybe.of(
{ name: 'Dinah', age: 14 }
).map(prop('age')).map(add(10))
// Just(24)
在从书中复制的这个示例中,第一个语句可以正常工作,但第二个得到一个TypeError
. 这似乎完全违背了 的宗旨Maybe
。还是我误解了什么?
解决方案
更新:2019 年 8 月
很高兴你问这个问题,我最初也对行为上的差异感到惊讶。正如其他人所回应的那样,这归结为Frisby Mostly Adequate Guide 实施的编码方式。“不规则”实现细节与isNothing
s 函数实现屏蔽value
传入 using的 null 或 undefined 的方式有关Maybe.of
:
get isNothing() {
return this.$value === null || this.$value === undefined;
}
如果您参考其他实现 - 然后使用Maybe.of()
创建您的Maybe
确实允许您传递 a null
orundefined
为Just
案例的值并实际打印例如Maybe.Just({ value: null })
相反,当使用 Folktale 时,创建将根据输入的值分配 a或的Maybe
using 。Maybe.fromNullable()
Just
Nothing
这是提供的代码的工作版本:
const Maybe = require("folktale/maybe");
const {
flip,
concat,
toUpper,
path,
pathOr,
match,
prop,
add
} = require("ramda");
console.log(Maybe.of("Malkovich Malkovich").map(match(/a/gi)));
//-> folktale:Maybe.Just({ value: ["a", "a"] })
console.log(Maybe.fromNullable(null).map(match(/a/gi)));
//-> folktale:Maybe.Nothing({ })
最后,这里有一个 Maybe 的演示实现,经过编码使用fromNullable
(类似于 Folktale 实现)。我从我认为强烈推荐的书 - Luis Atencio 的 JavaScript 函数式编程中获取了这个参考实现。他在第 5 章的大部分时间里都清楚地解释了这一点。
/**
* Custom Maybe Monad used in FP in JS book written in ES6
* Author: Luis Atencio
*/
exports.Maybe = class Maybe {
static just(a) {
return new exports.Just(a);
}
static nothing() {
return new exports.Nothing();
}
static fromNullable(a) {
return a !== null ? Maybe.just(a) : Maybe.nothing();
}
static of(a) {
return Maybe.just(a);
}
get isNothing() {
return false;
}
get isJust() {
return false;
}
};
// Derived class Just -> Presence of a value
exports.Just = class Just extends exports.Maybe {
constructor(value) {
super();
this._value = value;
}
get value() {
return this._value;
}
map(f) {
return exports.Maybe.fromNullable(f(this._value));
}
chain(f) {
return f(this._value);
}
getOrElse() {
return this._value;
}
filter(f) {
exports.Maybe.fromNullable(f(this._value) ? this._value : null);
}
get isJust() {
return true;
}
toString () {
return `Maybe.Just(${this._value})`;
}
};
// Derived class Empty -> Abscense of a value
exports.Nothing = class Nothing extends exports.Maybe {
map(f) {
return this;
}
chain(f) {
return this;
}
get value() {
throw new TypeError("Can't extract the value of a Nothing.");
}
getOrElse(other) {
return other;
}
filter() {
return this._value;
}
get isNothing() {
return true;
}
toString() {
return 'Maybe.Nothing';
}
};
推荐阅读
- node.js - 猫鼬模式病毒和异步等待
- java - 正则表达式拆分 (|)
- tsql - 使用 CASE 函数过滤表中的数据
- javascript - react-native 中的 firebase 出现“c.call 不是函数”错误
- jquery - jQuery datepicker 恢复以允许所有日期
- python - 在 request.session 中存储 OAuth 凭据是否安全?
- windows - wsl 安装包优先于 windows
- flutter - 如何自动加载对话框并在颤动中关闭?
- python - 如何防止我的 python 列表自动将字节转换为整数?
- c# - 如何重新排序方法执行