6

私は最近、一般的な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か?

4

1 に答える 1

14

これは、失敗が許される計算をモデル化するのに役立ちます。

たとえば、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

さて、挿入後に最適化を行うのは良いことですが、重要ではありません。したがって、この使用法を見ることができます:

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

この関数は 2 つの int を挿入し、DB の最適化を試みますが、失敗した場合 (誰かがその時点で何かを挿入していたなどの STM の理由により)、大したことではありません。とにかく進みます。

optionalSTM、および のエラーモナドControl.Monad.Error、およびさまざまなもので動作します。確かに純粋な計算にも。

于 2012-02-29T14:43:02.060 に答える