Haskell StateT和ExceptT链

Mic*_*icz 0 monads haskell monad-transformers

我不是很好的哈斯克尔程序员.我的任务是在我的大学编写一个编译器,我选择了haskell,因为它是用于此目的的好工具.我使用monads StateT和ExcepT,所以我有类型:

type Runner r s = StateT s (ExceptT LatteError IO) r
type RT r s = IO (Either LatteError (r, s))
Run Code Online (Sandbox Code Playgroud)

我用它创建walk一个程序树并生成asm代码,它可以按我的意愿工作.作为在树上行走的主要功能我使用

rProgram :: Program -> Runner [String] CompileState
Run Code Online (Sandbox Code Playgroud)

并解压缩结果我使用的功能

runR program = runExceptT (runStateT (rProgram program) initialCompileState)
Run Code Online (Sandbox Code Playgroud)

我想要做的不是有一些验证器,如类型检查,身份存在检查,我知道写它们.让我告诉我

tcProgram :: Program -> Runner () TypeCheckState
ieProgram :: Program -> Runner () IdentExistanceState
Run Code Online (Sandbox Code Playgroud)

我想以优雅的方式运行它们,并且throwError指示失败.如何把像他们这样的很多功能放在一起?

Ben*_*son 5

lens有一个zoom组合器,它使用镜头"放大"状态的一部分.

zoom :: Lens' s t -> State t a -> State s a
Run Code Online (Sandbox Code Playgroud)

(通常情况下lens,实际类型zoom比这更复杂,但这是一种考虑它的简单方法.)

所以我们有

zoom _1 . tcProgram :: Program -> Runner () (TypeCheckState, t)
zoom _2 . ieProgram :: Program -> Runner () (s, IdentExistenceState)
Run Code Online (Sandbox Code Playgroud)

所以

liftA2 (>>) (zoom _1 . tcProgram) (zoom _2 . ieProgram) :: Program -> Runner () (TypeCheckState, IdentExistenceState)
Run Code Online (Sandbox Code Playgroud)