2012-02-29 2 views
5

`のために私は最近、ジェネリックControl.Applicative.optionalコンビネータつまずいてきました:非パーサの例はControl.Applicative.optional`

optional :: Alternative f => f a -> f (Maybe a) 
optional v = Just <$> v <|> pure Nothing 

が、私はずっとそのコンビネータのための実用的な使用をしないでください。例えばこのようなリストやMaybe純粋なファンクタに適用された場合、結果は非常に便利なように見えるしません:

> optional [1,2,3] 
[Just 1,Just 2,Just 3,Nothing] 

> optional Nothing 
Just Nothing 

> optional (Just 1) 
Just (Just 1) 

...何がoptionalのより賢明な用途でしょうか?

+3

まあ、パーサーは気にしています:) –

+2

最近、Cafeには、オプションのものと同じユースケース、つまりパーサーと「失敗する可能性のあるもの」を持つ「some」と「many」について長い議論がありました。 .. http://www.haskell.org/pipermail/haskell-cafe/2011-12/12/097476.html –

答えて

13

これは、失敗することが許される計算をモデル化するのに便利です。

たとえば、あなたがSTMを扱っていることを言うと、これらの機能を持ってみましょう:

-- A database of Ints stored in a TVar 
intDatabase :: TVar (ComplexDatabaseStructure Int) 

-- Inserts an Int in the int database. 
insertInt :: Int -> STM() 

-- Organizes the DB so that it is more efficient 
optimizeDb :: STM() 

-- Checks whether an Int is in the DB 
lookupInt :: Int -> STM Bool 

、最適化は、挿入後にやるのはいいですが、それは重要ではありません。ですから、この使用状況を見ることができる:この関数は、2つのint、試行 DBを最適化するために挿入し、それが失敗した場合(理由はSTMの理由で、その誰かのように一度に何かを挿入した)

insert2AndCheck1 a b c = 
    insertInt a *> insertInt b *> optional optimizeDb *> lookupInt c 

、大したことではありません。私たちはちょうどとにかく行く。

optionalは、STM、およびControl.Monad.Errorのエラーモナドで動作します。確かに純粋な計算のためにも。