我最近偶然发现了通用Control.Applicative.optional
组合器:
optional :: Alternative f => f a -> f (Maybe a)
optional v = Just <$> v <|> pure Nothing
Run Code Online (Sandbox Code Playgroud)
但是我对这个组合器没有多少实际用处; 例如,当应用于诸如列表之类的纯函子时Maybe
,结果似乎不太有用:
> optional [1,2,3]
[Just 1,Just 2,Just 3,Nothing]
> optional Nothing
Just Nothing
> optional (Just 1)
Just (Just 1)
Run Code Online (Sandbox Code Playgroud)
......什么是更明智的应用optional
?
dfl*_*str 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
Run Code Online (Sandbox Code Playgroud)
现在,插入后优化很好,但并不重要.所以你可以看到这种用法:
insert2AndCheck1 a b c =
insertInt a *> insertInt b *> optional optimizeDb *> lookupInt c
Run Code Online (Sandbox Code Playgroud)
此函数插入两个整数,然后尝试优化数据库,但如果失败(因为STM原因,就像有人在当时插入某些东西),这不是什么大问题; 我们还是继续.
optional
适用于STM,还有任何错误monad Control.Monad.Error
,以及许多不同的东西; 当然也适用于纯计算.
归档时间: |
|
查看次数: |
291 次 |
最近记录: |