Ato*_*ton 3 monads haskell haskell-snap-framework
我正在使用Snap框架,我常常遇到这样的情况:我根据从表单字段获得的参数进行数据库查找.
考虑例如以下两个功能
getParam :: (MonadSnap m) => ByteString -> m (Maybe ByteString)
doLookup :: (MonadIO (m b v), MonadSnaplet m, MonadState s (m b b), HasAcid s UrlDB) => ByteString -> m b v (EventResult QueryByURL)
Run Code Online (Sandbox Code Playgroud)
其中UrlDB是整数和URL之间的映射.第二功能的复杂类型特征是由于使用酸状态并最终导致Maybe Integer.
queryByURL :: Text -> Query UrlDB (Maybe Integer)
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的处理程序看起来像
indexHandler :: Handler MyApp MyApp ()
indexHandler = do
mUrl <- getParam "url"
case mUrl of
Nothing -> render "index"
Just url -> do
mId <- doLookup $ url
case mId of
Nothing -> render "index"
Just i -> do
fancyStuffWith i
render "index"
Run Code Online (Sandbox Code Playgroud)
现在,让我烦恼的第一件事是案例表达的阶梯式.第二件事是三重外观render "index".基本上,每当两个Maybe值中的一个为Nothing时,我想返回一个默认视图.
最干净的方法是什么?
这就是MaybeT monad变换器的用途.你的代码可以像这样写.
indexHandler :: Handler MyApp MyApp ()
indexHandler = do
runMaybeT $ do
url <- MaybeT $ getParam "url"
i <- MaybeT $ doLookup url
fancyStuffWith i
render "index"
Run Code Online (Sandbox Code Playgroud)
该错误包拉在一起,这些东西,并增加了很多的方便功能与他们合作.除了MaybeT之外,EitherT monad变换器也可以执行类似的操作,但会跟踪错误消息,以便您可以跟踪计算失败的时间.