所以我想要一个表示包含一组节点类型的树的类型.我也想要表示在重叠集上定义的类似树的类型.这是Typed AST问题的另一个版本.假设我的节点类型池是:
data Lit = Lit Int
data Var = Var String
data Hole = Hole Int
Run Code Online (Sandbox Code Playgroud)
解析树可以包含Lit
s或Var
s但不包含Hole
s.第二种称为模板的树可以包含Lit
s,Var
s或Hole
s.
为了简单起见,有一种类型的递归节点被称为Add
.
data Parse = A Lit | B Var
data Template = C Lit | D Var | E Hole
data Tree a = Leaf a
| Add (Tree a) (Tree a)
Run Code Online (Sandbox Code Playgroud)
所以现在我可以声明数据,我仍然可以对它进行模式匹配,唯一的问题是语法杂乱.
aParse = Add (A Lit 3) (B Var "x")
aTemplate = Add (C Lit 4) …
Run Code Online (Sandbox Code Playgroud) 我在状态monad中有一堆有状态函数.程序中的某一点需要有一些IO操作,所以我将IO包装在StateT中,得到一对这样的类型:
mostfunctions :: State Sometype a
toplevel :: StateT Sometype IO a
Run Code Online (Sandbox Code Playgroud)
为了简单起见,我不想将IO上下文传递给主要的函数集,我想避免将它们包装在monad堆栈类型中.但是为了从顶层功能中调用它们,我需要类似于升力的东西,但我并不是想从内部单子中提升一个值.相反,我想将StateT monad中的状态转换为State monad中的等价物.要做到这一点,我有以下内容:
wrapST :: (State Sometype a) -> StateT Sometype IO a
wrapST f = do s <- get
let (r,s2) = runState f s
put s2
return r
Run Code Online (Sandbox Code Playgroud)
然后这用于交错,如下所示:
toplevel = do liftIO $ Some IO functions
wrapST $ Some state mutations
liftIO $ More IO functions
....
Run Code Online (Sandbox Code Playgroud)
它似乎是一个相当明显的代码块,所以我想知道这个函数是否有标准名称,它已经在标准库中的某个地方实现了?我试图保持描述简单,但显然这延伸到将一个变换器拉出堆栈,将包装的值转换为变换器类型的表兄弟,跳过堆栈中的下面的monad,然后将结果推回到结束.