1

Data.Map を使用して文字列を関数にマップしようとしています。私が抱えている問題は、私のプログラムの主なエラー処理が、Either モナドを使用し、Map.lookupを返すことMaybe ([SomeVal] -> Either ValError SomeVal)です。Map.lookupこの場合、Either モナドをうまく扱うにはどうすればよいでしょうか?

apply :: String -> [SomeVal] -> Either ValError SomeVal
apply s args = (Map.lookup s prims) >>= \fn -> fn args

prims :: Map String ([SomeVal] -> Either ValError SomeVal)
prims = Map.fromList
    [("key", function)
    ,("key2", function2)
    ]

::> apply "key" [val1, val2, val3]
4

3 に答える 3

6

他の回答は、一般的になる方法Maybeを説明しています。Eitherただし、Data.Map具体的には の代わりに をMap.lookup使用できますMap.findWithDefault。これは でラップされず、存在しないMaybeキーの処理方法を選択できます。

于 2013-11-11T06:00:37.587 に答える
1

それは、ケースをどのように処理するかによって異なりますNothing。キーが常にそこにあると主張したい場合 (悪い考えです)

import Data.Maybe
apply s args = (prims ! s) args

しかし、よりスマートな方法は、何も見つからない場合に適切な値を持つことです。ValErrorおそらく、いくつかのコンストラクターが必要になるでしょう

ValError = ...
         | NoKey String
         ...
apply s args = maybe (Left $ NoKey s) ($args) $ M.lookup s prims

または単に維持したいMaybe

apply :: String -> [SomeVal] -> Maybe (Either ValError SomeVal)

これらの方法のいずれも、キーが見つからなかった場合に、より適切なセマンティクスを提供します。どちらを選択するかは、ほとんどの場合好みですapply。API のかなり基本的な部分を非常に多く作成ValErrorして、それについて知っておく必要がある場合は、1 がうまく機能します。

それ以外の場合、2 を使用するのは面倒ですが、既存のコードを変更する必要がないため快適です。

于 2013-11-11T05:18:16.000 に答える