当我读到提升的概念时,它是这样实现的(在 Javascript 中)
const liftA2 = f => (a, b) => b.ap(a.map(f));
我意识到有一种情况liftA2
会产生错误:when b
is a Right
/ Just
and a
is a Left
/ ,因为当我们需要它成为部分应用的函数时Nothing
,映射Left
/不会对值做任何事情。Nothing
Whena
和b
are both aLeft
它不会爆炸,但当然返回Left
的值将是我认为可能是一个问题的值,b
具体取决于您的期望。
提升与这些类型一起使用的功能是否是一回事?在使用这样的功能之前,我是否应该系统地明确地防范这些情况?上述实现是否正确/完整?
您将在下面找到有关该问题的更多详细信息
让我们定义函数来提升const add = a => b => a + b;
在基本
Wrapper
实现of
的情况下ap
,map
我们可以跟踪正在发生的事情class Wrapper { constructor(value) { this.value = value; } static of(value) { return new Wrapper(value); } map(f) { return Wrapper.of(f(this.value)); } ap(a) { return this.map(a.value); } } const a = Wrapper.of(1); const b = Wrapper.of(2); // liftA2 const tmp = a.map(add); // Wrapper { λ } b.ap(tmp); // Wrapper { 3 }
但是
Either
or的事情Maybe
是他们有一个Left
/Nothing
casemap
并且打算不做任何特别的ap
事情class Left { constructor(value) { this.value = value; } static of(value) { return new Left(value); } map(f) { return this; } ap(a) { return this; } } class Right{ constructor(value) { this.value = value; } static of(value) { return new Right(value); } map(f) { return Right.of(f(this.value)); } ap(a) { return this.map(a.value); } } const a = Left.of(1); const b = Right.of(2); // liftA2 const tmp = a.map(add); // Left { 1 } b.ap(tmp); // Error because tmp's value is not a function