<%= f.select :to_vote, select_list, selected: 'ineligible' %>
方法具有Chain的值必须提供
chain
方法。连锁,链条 方法有一个参数:
chain
m.chain(f)
必须是返回值的函数
- 如果
f
不是函数,则f
的行为未指定。chain
必须返回相同链的值- 醇>
f
必须返回相同链的值
给出monad选项的简单实现:
chain
为了保证// prototypes:
const someProto = {
of(x) { return some(x) },
map(f) { return some(f(this.x)) },
ap(ftor) { return ftor.map(this.x) },
join() { return this.x },
chain(mf) { return this.map(mf).join() }
};
const noneProto = {
of() { return this },
map() { return this },
ap() { return this },
join() { return this },
chain() { return this }
};
// factories:
function some(x) {
return Object.assign(Object.create(someProto), {x: x});
}
function none() {
return Object.assign(Object.create(noneProto), {x: null});
}
始终返回选项monad,我必须确保chain
(monadic函数)始终返回一个。这是不可能的,因为mf
不是实现的一部分。相反,它是在使用monad时定义的:
mf
在第二个方法应用程序中,传递的函数不返回monad,这导致monadic计算的展开结果。我可以通过鸭子打字向// auxiliary function:
const sub = y => x => x - y;
let a = some(2);
let b = some(3);
a.chain(x => b.chain(y => some(sub(x)(y)))); // {x: 1}
a.chain(x => b.chain(y => sub(x)(y))); // 1 - ouch!
或chain
添加类型检查来解决问题 - 但这会非常难看。
为什么规范要求类型安全? Javascript是动态类型的,我宁愿编写适当的单元测试,而不是在运行时执行类型检查。我会违反规范吗?
答案 0 :(得分:1)
在第二个示例中,您应该使用 .map():
a.chain(x => b.map(y => sub(x)(y)));
然后一切都遵循规则。
为了比较,这里是等效的Haskell签名:
fmap :: m a -> (a -> b) -> m b -- same as .map()
(>>=) :: m a -> (a -> m b) -> m b -- same as .chain()
因此,如果您的函数返回monadic值,请使用.chain()
。否则使用.map()
。