因为我是showed you these operators的人,所以我将简单介绍一下为什么我使用它们。
回顾一下,一个仿函数是一种构造,让您使用的fmap
功能的功能适用于“包装”的价值。在Either
类型构造函数的特定情况下(部分应用,在本例中为String
),可以将函数应用于Right
值,但如果应用于Left
值(您的错误),则忽略该函数。它提供了一种错误传播方式,而不必检查错误。
fmap f (Right x) = Right (f x)
fmap f (Left y) = Left y
一种适用函子是类似的,除了该函数本身可以缠绕就像它被施加到该参数。 <*>
运算符展开两个操作数,不像fmap
只展开其右操作数。
Right f <*> Right x = Right (f x)
Left f <*> _ = Left f
_ <*> Left y = Left y
通常情况下,你不自己包的功能:他们使用fmap
的功能部分适用于包裹值的结果是:
fmap (+) (Right 3) == Right (+ 3)
fmap (+) (Left "error") == Left "error"
所以,当我们与Either
值工作时,使用<$>
(infix fmap
)和<*>
让我们假装我们正在使用常规值,而不用担心它们是否用Left
或Right
包装。 Right
值提供了预期的Right
包装的答案,并且Left
值被保留。在二元运算符的情况下,只返回第一个值Left
,但这通常就足够了。
(+) <$> Left "x undefined" <*> Left "y undefined" == Left "x undefined" <*> Left "y undefined"
== Left "x undefined"
(+) <$> Left "x undefined" <*> Right 9 == Left "x undefined" <*> Right 9
== Left "x undefined"
(+) <$> Right 3 <*> Left "y undefined" == Right (+ 3) <*> Left "y undefined"
== Left "y undefined"
(+) <$> Right 3 <*> Right 9 == Right (+3) <*> Right 9
== Right 12
最后,使用Either String
的Applicative
比如让我们结合来评价两个子表达式的结果,而不必明确检查的eval
要么递归调用实际上成功。成功的递归调用导致成功;任何一个调用中的错误都将用作顶级调用的相同错误。
你应该在Hoogle或Hayoo上查找它们。 – dfeuer
我不知道如何搜索他们 –
好吧,首先找到他们与谷歌。完成后,在搜索字段中输入所需的运算符。 – dfeuer