处理`Maybe`时如何避免`case`

时间:2016-04-28 20:01:49

标签: haskell

我正在Haskell中编写解释器,我有map:name_of_function - >定义功能。

<form method="post">
 <input type="text" name="myText" />
 <input type="submit" name="ask" class="tbutton" value="ask" />
</form>

<?php
   if(isset($_POST['ask'])){
      echo($_POST['myText']);
   }
?>

我的翻译monad:

Map String Defun

正如你所看到的,“最后一个”monad是type InterpreterMonad = StateT (EnvFun, (Stack EnvEval)) (ErrorT String IO ) ()

现在,当我想处理调用函数时:

ErroT

正如您所见,我必须使用 handleFCall :: Stmt -> InterpreterMonad handleFCall (VarName name) args = get >>= \(envFun, contextStack) -> case (Map.lookup (VarName name) envFun) of Nothing -> throwError "Err" (Just x) -> DoSthOther 。不过我使用的是case,所以我想在这里避免使用>>=。但是,case of返回Map.lookup失败,我想添加错误消息。

我没有Haskell的经验所以我不知道如何处理它。更重要的是,欢迎对我的代码提出批评。

干杯。

2 个答案:

答案 0 :(得分:4)

使用case语句没有错,虽然使用do notation重新格式化,你的函数看起来更像

handleFCall (VarName name) args = do
    (envFun, contextStack) <- get
    case Map.lookup (VarName name) envFun of
        Nothing -> throwError "Err"
        Just x -> doSthOther x

其他Haskell程序员会更熟悉。但是,如果您真的想避免使用案例,只需使用maybe函数:

handleFCall (VarName name) args = do
    (envFun, contextStack) <- get
    maybe (throwError "Err") doSthOther $ Map.lookup (VarName name) envFun

>>=

handleFCall (VarName name) args
    = get >>= 
        (\(envFun, contextStack) ->
            maybe (throwError "Err") doSthOther
                $ Map.lookup (VarName name) envFun
        )

但我个人觉得案例陈述更具可读性。

答案 1 :(得分:1)

errors packageControl.Error.Util中有以下操作(并从Control.Error重新导出):

-- You can turn `Maybe` into `Either` by supplying a constant to use
-- for the `Left` case.
note :: a -> Maybe b -> Either a b

-- Ditto for `MaybeT` and `ExceptT`
noteT :: Monad m => a -> MaybeT m b -> ExceptT a m b

-- And there are useful shortcuts for other combinations
failWith :: Applicative m => e -> Maybe a -> ExceptT e m a

failWith特别看起来在这里非常适合,像这样的表达式就可以了。

failWith "Err" (Map.lookup (VarName name) envFun)

请注意,您在示例中使用的ErrorT转换器已被弃用,而不是ExceptT(因为上面的签名正在使用),所以您必须相应地更改您的代码以使用errors包。另一方面,这些功能非常简单,如果您愿意,可以自己烘焙。