1

Haskel の Maybe-idiom を適用する方法を理解しようとしています.. http://en.wikibooks.org/wiki/Haskell/Understanding_monads/Maybe を読んでます。Maybeこの値が>>=演算子を介して伝播すること。

URL の例:

次に、政府データベースのルックアップの結果を 3 回目のルックアップで使用したい場合 (たとえば、登録番号を調べて、自動車税がかかっているかどうかを確認したい場合)、getRegistrationNumber 関数を拡張できます。

getTaxOwed :: String       -- their name
           -> Maybe Double -- the amount of tax they owe
getTaxOwed name = 
  lookup name phonebook >>=
    (\number -> lookup number governmentalDatabase) >>=
      (\registration -> lookup registration taxDatabase)

または、do-block スタイルを使用します。

getTaxOwed name = do
  number       <- lookup name phonebook
  registration <- lookup number governmentalDatabase
  lookup registration taxDatabase

質問:

エラーハンドリングはどのように処理すればよいですか? ほとんどのコードは、どこで問題が発生したかを知ることで恩恵を受けると思います。「電話帳にも政府データベースにも John Doe が見つからなかった」と報告するだけでなく、どのリソースに問題があったかを報告する必要があります。

4

2 に答える 2

8

Either String基本的に次のように定義されている のモナド インスタンスを使用できます。

instance Monad (Either String) where                                             
  fail msg = Left msg                                                            
  return x = Right x                                                             

  Left msg >>= k = Left msg                                                      
  Right x  >>= k = k x

(実際の定義はもう少し複雑です。)

次に、辞書をラベルとルックアップ テーブルで構成されるペアとして定義すると、

type Dict a b = (String, [(a, b)])

phonebook' :: Dict String Int
phonebook' = ("phone book", phonebook)

governmentalDatabase' :: Dict Int Int
governmentalDatabase' = ("governmental database", governmentalDatabase)

taxDatabase' :: Dict Int Double
taxDatabase' = ("tax database", taxDatabase)

ここでphonebook、 、governmentalDatabase、およびtaxDatabaseは以前に定義したとおりですが、Either String-monadで結果を返す別のモナド検索関数を使用できます。

lookup' :: (Eq a, Show a) => a -> Dict a b -> Either String b
lookup' key (descr, table) = case lookup key table of
  Nothing  -> Left ("couldn't find " ++ show key ++ " in " ++ descr)
  Just val -> Right val

モナドの力を例証すると、クライアント関数で変更する必要があるのは、型シグネチャだけです。

getTaxOwed :: String               -- their name                                 
           -> Either String Double -- either an error message                    
                                   -- or the amount of tax they owe              
getTaxOwed name = do
  number       <- lookup' name phonebook'
  registration <- lookup' number governmentalDatabase'
  lookup' registration taxDatabase'

未知の名前でこの関数を実行すると、次の結果が得られます。

> getTaxOwed "Joe"
Left "couldn't find \"Joe\" in phone book"
于 2012-08-13T10:47:19.543 に答える
5

Maybe データ型には、エラーを通知するための値「N​​othing」しかありません。特定のエラー メッセージを返したい場合は、「左 a」または「右 a」のいずれかの値を返すことができるデータ型「Either」をお勧めします。http://learnyouahaskell.com/for-a-few-monads-more#errorでそれを使用する方法の詳細を読んでください

于 2012-08-13T09:24:43.963 に答える