haskell - 将 State monad 与 Either-style 错误传播相结合

标签 haskell monad-transformers state-monad either

我对 Haskell 相当陌生。我试图通过将 Either 视为 monad 来将 State monad 与错误传播结合起来。我想以不需要显式处理状态或错误的方式递归抽象语法树(例如,用于在语句和表达式上编写解释器)。我的印象是,最简单的方法是使用 exceptT monad 转换器。这是我编译的示例代码:

import Control.Monad.Except
import Control.Monad.State
import qualified Data.Map.Strict as M

-- simple expression language supporting crude let bindings
data Exp = Lit Int | Var String
         | Add (Exp, Exp) | Let (String, Exp, Exp) deriving Show

okExp =  -- let x = 2 in let y = x + 3 in x + y -- evaluate to 7
    Let ("x", Lit 2,
             Let ("y", Add (Var "x", Lit 3),
                      Add (Var "x", Var "y")))
badExp = Var "x"  -- error: x is not defined

type St = M.Map String Int
initialState :: St
initialState = M.empty

type EvalMonad = ExceptT String (State St)

evalExp :: Exp -> EvalMonad Int
evalExp (Lit n) = return n
evalExp (Var v) = do
    mp <- lift get
    case M.lookup v mp of
        Just i -> return i
        Nothing -> throwError (v ++ " not found")
evalExp (Add (a, b)) = do
    x <- evalExp a
    y <- evalExp b
    return (x + y)

我希望在简单的示例(例如,okExp、badExp)上运行 evalExp。我不确定三件事:
  • 如何将初始状态纳入计算?
  • 如何使用 runExceptT 提取结果?
  • (更笼统):这是解决这个问题的“正确”方法吗?
  • 最佳答案

    看起来是一个很好的开始!这是一个小例子,展示了如何使用 runExceptTrunState一起在 ghci 中:

    > runState (runExceptT (evalExp (Add (Lit 3, Lit 4)))) initialState
    (Right 7,fromList [])
    > runState (runExceptT (evalExp (Add (Lit 3, Var "x")))) initialState
    (Left "x not found",fromList [])
    

    关于haskell - 将 State monad 与 Either-style 错误传播相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60622772/

    相关文章:

    parsing - Haskell - 使用状态与替代方案

    Haskell MonadState 实现 put 和修改

    algorithm - 是否有任何允许并行加法的自然数代数表示?

    networking - 将 Haskell 的 SimpleHTTP 与代理一起使用?

    haskell - 存在类型和单子(monad)更改器(mutator)

    functional-programming - 状态单子(monad)的目的是什么?

    haskell - 一次处理列表 1..n 个元素,无需显式递归

    haskell - 无法将 Database.HDBC.Sqlite3 添加到堆栈文件

    scala - 在scalaz中将状态分层

    parsing - 使普通的一元函数与等效的一元转换器一起工作