2016-12-06 94 views
-3

haskell中的那些运算符是什么?和< *> 我有他们在这样的线:

class Evaluable e where 
    eval :: (Num a, Ord a) => (Ident -> Maybe a) -> (e a) -> (Either String a) 
    typeCheck :: (Ident -> String) -> (e a) -> Bool 

instance Evaluable NExpr where 
    eval lookup (Plus left right) = (+) <$> eval lookup left <*> eval lookup right 
+3

你应该在Hoogle或Hayoo上查找它们。 – dfeuer

+0

我不知道如何搜索他们 –

+1

好吧,首先找到他们与谷歌。完成后,在搜索字段中输入所需的运算符。 – dfeuer

回答

4

因为我是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)和<*>让我们假装我们正在使用常规值,而不用担心它们是否用LeftRight包装。 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 StringApplicative比如让我们结合来评价两个子表达式的结果,而不必明确检查的eval要么递归调用实际上成功。成功的递归调用导致成功;任何一个调用中的错误都将用作顶级调用的相同错误。

3

<$>操作者是fmap中缀形式。它允许您将纯函数应用到属于Functor类的某些参数类型的值中。 <$>的类型是(a -> b) -> f a -> f b

<*>运营商非常相似<$>。它允许您将包装到参数类型中的函数应用到包装为相同参数类型的值中。 <*>的类型是f (a -> b) -> f a -> f b

1

在这种特殊情况下,这是一种结合eval的结果的方法。 如果表达式的一部分失败,那么整个表达式失败。

通过这种方式,可以将应用程序逻辑的错误处理分开并避免复杂的嵌套case ... of

要完全理解这一点,我会建议先阅读仿函数,然后应用仿函数。

与此同时,您可以使用Maybe和Either,并使用case表达式编写等效代码。

相关问题