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

该函数插入两个整数,然后尝试优化数据库,但如果失败(由于 STM 的原因,比如当时有人插入了一些东西),这没什么大不了的;反正我们就继续。

optional适用于 STM,以及 中的任何错误单子Control.Monad.Error,以及许多不同的东西;当然也适用于纯计算。

于 2012-02-29T14:43:02.060 回答