考虑以下构成
M(v2)
是否有一个monad identity(v)
允许上述内容评估为Either
?
我正在尝试建模程序应该应用完整的转换链直到第一次转换失败的情况,在这种情况下,链计算到最后一次成功转换。在最坏的情况下,整个链代表Option
。
var troll = document.getElementById('troll');
troll.addEventListener('dragover', (e) => {
e.preventDefault();
e.target.style.left = e.clientX + 'px';
e.target.style.top = e.clientY + 'px';
}, false);
和img {
width: 100px;
cursor: pointer;
position: absolute;
}
等Monad不符合此要求,因为在出错时他们会将整个链评估为错误,而链条始终要求评估成功。换句话说,我希望程序尽可能多地尝试,但如果它不能做任何事情,那也没关系。
答案 0 :(得分:2)
Either
monad 完全符合您的要求。 Either
界面中没有任何内容强制您使用Left
和Right
案例的不同类型。特别是,Left
类型参数可以与Right
类型参数相同,它们都可以等于Result
(或" PartialSuccess
&# 34;?),您可以在其中定义构成Result
的内容。
因此,您只需将所有transformN
函数声明为返回类型
def transformN(previousStep: Result): Either[Result, Result] = ???
最后,你将fold
改为一个结果:
val res: Result = (for {
v1 <- transform1(v)
v2 <- transform2(v1)
v3 <- transformThatErrors(v2)
v4 <- transfrom4(v3)
} yield v4).fold(
partialRes => partialRes,
completeRes => completeRes
)
甚至只是
.fold(identity, identity)
第一次转换失败后,Either
会将部分结果打包为Left
,并将其返回,而不应用任何进一步的转换。如果每个转换步骤都成功,则最终结果将返回Right
。无论转换何时停止,最终fold
都会从中提取(部分)结果。
如果我理解正确,那么您可能想出的每个其他monad M
与Either[Result, Result]
基本相同,其中一些特殊getResult
方法等同于{{ 1}},所以不需要不必要地增加实体。