2016-12-06 5 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

まず、Googleで検索してください。検索フィールドに入力した演算子を入力します。 – dfeuer

答えて

4

私はshowed you these operatorsの人ですから、なぜ私がそれらを使用したかについて簡単に説明します。レビューに


、ファンクタは、あなたが「ラップ」の値に関数を適用するfmap機能を使用することができますタイプのコンストラクタです。 型のコンストラクタ(この場合は部分的に適用されますが、この場合はString)では、Rightの値に関数を適用できますが、値がLeft(エラー)の場​​合は無視されます。これは、エラーをチェックすることなく、エラー伝播の方法を提供します。機能自体はちょうどそれが適用される引数のようにラップすることができます以外

fmap f (Right x) = Right (f x) 
fmap f (Left y) = Left y 

のApplicativeファンクタは、類似しています。 <*>演算子は、右オペランドのみをアンラップする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値を操作しているとき、 <$>(接尾辞fmap)と<*>を使用すると、Leftまたは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のいずれかの再帰呼び出しが実際に成功した場合には明示的にチェックすることなく、2つの部分式の評価結果を結合することができます。成功した再帰呼び出しは成功に終わります。いずれかのコールのエラーがトップレベルコールの同じエラーとして使用されます。

3

<$>オペレータがfmapの中置形です。 Functorクラスに属するパラメトリック型にラップされた値に純関数を適用することができます。 <$>のタイプは(a -> b) -> f a -> f bです。

<*>演算子は<$>と非常によく似ています。パラメトリック型にラップされた関数を、同じパラメトリック型にラップされた値に適用することができます。 <*>のタイプはf (a -> b) -> f a -> f bです。

1

この特定のケースでは、これはevalの結果を組み合わせる方法です。 式の一部が失敗している場合は、式全体が失敗しています。

このように、アプリケーションロジックのエラー処理を分離し、複雑なネストされたcase ... ofを回避することが可能です。

これを完全に理解するには、最初にファンクタを読んでから、適切なファンクタを読むことをお勧めします。

これと並行して、MaybeとEitherで遊んで、caseの式を使って同等のコードを書くことができます。

関連する問題

 関連する問題