我在玩Maybe和Monad类型(Chaining,根据返回值应用条件函数,还返回链接函数失败等错误消息)。所以它对我来说似乎就像我们可以通过使用任一monad实现同样的和更多的事情。所以我的问题是这些之间的实际或概念差异?为什么我们需要可能Monad在任一Monad
回答
你当然是对的,Maybe a
是同构于Either Unit a
。问题是,他们往往在语义上用来表示不同的东西,有点像回到null
和投掷之间的差异NoSuchElementException
:
Nothing
/None
表示“期待”丢失的东西,而Left e
表示无论出于何种原因,在获取它时出现错误。
这就是说,我们甚至可以将二者结合起来的东西,如:
query :: Either DBError (Maybe String)
我们表达缺失值(DB NULL
)的两种可能性,并在连接错误,DBMS ,或者其他什么(不是说没有更好的设计,但你明白了)。
有时,边界是流动的;对于saveHead :: [a] -> Maybe a
,我们可以说错误的预期可能性是按照函数的意图编码的,而像saveDivide
可能编码为Float -> Float -> Either FPError Float
或Float -> Float -> Maybe Float
,这取决于用例(再次,仅仅是一些愚蠢的例子...) 。
如果有疑问,最好的选择是使用带有语义编码的自定义结果ADT(如data QueryResult = Success String | Null | Failure DBError
),并优先选择Maybe
来处理“传统期望”的简单情况(主观点,但是大多数都可以,如果你获得经验)。
@ phg的回答非常好。我会附和东西清除了起来,让我当我学习他们:
Maybe
是一个(价值)或无 - 也就是说,你有一个值,或者您有什么Either
是逻辑分离,但你总是至少有一个(价值) - 即,你有另一个或,但不是两个。
Maybe
适用于您可能有或没有价值的地方 - 例如查找列表中的项目。如果列表中包含它,我们得到(Maybe x)
否则我们得到Nothing
Either
是在你的代码分支的完美表现 - 它会去一个或其他方式; Left
或Right
。我们使用助记符来记住它:Right
是对(正确)的方式; Left
是错误方式(错误)。这当然不是,而是最常见的。
我知道这些差异起初看起来很微妙,但实际上它们适用于非常不同的事情。
对于提及逻辑析取,你可以得到+1。这对于新来FP的人来说是非常平易近人的答案。 –
谢谢Jared。您的反馈意味着我很多^ _ ^ – naomik
嗯,你看,我们可以把这个说得极端,说所有的产品类型都可以用2元组和所有的非递归和类型来表示,由Either
。为了额外表示递归类型,我们需要一个fixpoint类型。
例如,为什么有4元组(a,b,c,d)
时我们还可以写(a, (b, (c,d)))
或(((a,b), c), d)
?
或者为什么有列表,以下情况也适用?
data Y f = Y (f (Y f))
type List a = Y ((,) (Either() a))
nil = Y (Left(), undefined)
cons a as = Y (Right a, as)
infixr 4 cons
numbers = 1 `cons` 2 `cons` 3 `cons` nil
-- this is like foldl
reduce f z (Y (Left(), _)) = z
reduce f z (Y (Right x, xs)) = reduce f (f z x) xs
total = reduce (+) 0 numbers
- 1. 为什么不是`Monad`类
- 2. 为什么此代码需要Monad约束?
- 3. 功能为Monad的
- 4. monad为什么不在scala中编写
- 5. 在IO monad中使用monad
- 6. 什么是Haskell`( - >)a` monad?
- 7. 为什么我们需要crossCheckMatching功能?
- 8. 为什么我们需要RBAC许可?
- 9. 为什么随机monad函数需要一个额外的参数?
- 10. 在海龟中编写ExitCodes。为什么没有Monad/Monad Transformer实例?
- 11. 为什么Control.Monad.Morph.hoist具有Monad约束?
- 12. State Monad,为什么不是元组?
- 13. 为什么Monad的排序是Set1?
- 14. 为什么Reader monad存储函数?
- 15. 为什么强制实施Maybe monad?
- 16. AccValidation为什么没有Monad实例?
- 17. Haskell称之为Hom Functor/Monad是什么?
- 18. 对一个错误monad证明了一些monad法我写了
- 19. 当monad变压器需要提升吗?
- 20. Haskell - 提取可能在Monad中
- 21. 为什么显然任何monad栈通常会派生MonadIO?
- 22. monad在monad变压器上下文
- 23. 为什么我们需要在JavaScript
- 24. Haskell:翻译为Monad
- 25. 为什么MonadFix的实例不能用于连续monad?
- 26. jQuery是一个monad
- 27. 使用免费Monad与任一
- 28. 为什么我可以在不提供monad的情况下调用monadic函数?
- 29. 作为变压器摘要monad作文
- 30. 如何在另一个Monad中使用IO Monad
我很震惊,这不是一个骗局。很好的问题。 –