2012-02-29 57 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

那麼,解析器會彈出想法:) – 2012-02-29 14:15:54

+2

最近有關Cafe的一些討論很多,關於'some'和'many'與'optional'有相同的用例,即解析器和「可能失敗的東西」。 .. http://www.haskell.org/pipermail/haskell-cafe/2011-December/097476.html – 2012-02-29 14:36:37

回答

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 

,優化是好的插入後做,但它並不重要。所以,你可以看到這種用法:

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

該功能用於插入兩個整數,然後嘗試來優化數據庫,但如果失敗(因爲STM着想,這樣的人是將當時的東西),這不是什麼大不了的事;反正我們繼續。

optional與STM一起工作,還有任何錯誤monad在Control.Monad.Error,和許多不同的東西;當然也適用於純粹的計算。