【发布时间】:2021-01-04 16:21:48
【问题描述】:
Functional Programming in C++,在第 214 页,参考了与 Haskell 的 Either 相同的 expected<T,E> monad,读取
[...] 只要您绑定到的任何函数返回错误,执行将停止并将该错误返回给调用者。
然后,在下面的标题中,它显示
如果你在包含错误的
expected上调用mbind[相当于Haskell 的>>=],mbind甚至不会调用转换函数; 它只会将该错误转发给结果。
这似乎“调整”了之前写的内容。 (我很确定 LYAH 或 RWH 在某处强调没有短路;如果您记得在哪里,请提醒我。)
确实,我从 Haskell 的理解是,在单子绑定链中,所有绑定都是真实发生的;那么他们如何处理作为第二个参数传递给他们的函数,取决于特定的 monad。
在Maybe 和Either 的情况下,当绑定传递Nothing 或Left x 参数时,第二个参数将被忽略。
不过,在这两种特定情况下,我想知道这样做是否会降低性能
justPlus1 = Just . (+1)
turnToNothing = const Nothing
Just 3 >>= turnToNothing >>= justPlus1
>>= justPlus1
>>= justPlus1
>>= justPlus1
>>= justPlus1
因为在这些情况下,链实际上除了它所做的之外什么都做不了,因为
Nothing >>= _ = Nothing
Left l >>= _ = Left l
【问题讨论】:
-
我认为答案是您无需为
Nothing之后的内容支付任何费用,但您确实需要为在此之前展开堆栈付费,但我并不完全确定。在某些情况下,继续传递样式应该在某些方面更有效,例如解析器组合器库使用 CPS 而不是Either来处理错误。 -
@Hjulle,这个 CPS 东西也是单子吗?
标签: c++ performance haskell functional-programming monads