我写简单的解释器,我想存储变量.到目前为止,我有:
-- MyEnv is a map from strings into integers
type MyEnv = M.Map String Int
type TCM a = ErrorT String (StateT MyEnv IO) a
Run Code Online (Sandbox Code Playgroud)
我有一个定义
ms_assgn :: Assgn -> TCM()
ms_assgn (Assgn (Ident ident) exp) = do
map <- get
w1 <- ms_exp exp
put (M.insert (ident w1 map))
Run Code Online (Sandbox Code Playgroud)
我得到了以下的错误:
Interpret.hs:118:5:
Couldn't match type `Envnt' with `a0 -> M.Map k0 a0 -> M.Map k0 a0'
When using functional dependencies to combine
MonadState s (StateT s m),
arising from the dependency `m -> s'
in the instance declaration in `Control.Monad.State.Class'
MonadState (a0 -> M.Map k0 a0 -> M.Map k0 a0) (StateT Envnt IO),
arising from a use of `put' at Interpret.hs:118:5-7
In a stmt of a 'do' block: put (M.insert (ident w1 map))
In the expression:
do { map <- get;
w1 <- ms_exp exp;
put (M.insert (ident w1 map)) }
Interpret.hs:118:20:
Couldn't match expected type `Integer -> Envnt -> k0'
with actual type `[Char]'
The function `ident' is applied to two arguments,
but its type `String' has none
In the first argument of `M.insert', namely `(ident w1 map)'
In the first argument of `put', namely `(M.insert (ident w1 map))'
Run Code Online (Sandbox Code Playgroud)
当我用put注释掉最后一行并用return()替换它时,它没有任何合理性,但至少它是编译的.ms_assgn函数我这样理解:
这有什么问题?任何提示?
这只是一组额外的括号.
M.insert (ident w1 map) -- wrong
Run Code Online (Sandbox Code Playgroud)
该insert函数具有类型k -> a -> Map k a -> Map k a,但是那些额外的括号意味着您正在调用ident它就像是一个函数.
M.insert ident w1 map -- correct
Run Code Online (Sandbox Code Playgroud)
但是,作为语义问题,如果ms_exp exp修改环境,您可能会遇到意外行为,因为这些更改将会丢失.我会在环境修改之上移动:
ms_assgn (Assgn (Ident ident) exp) = do
w1 <- ms_exp exp
map <- get
put $ M.insert ident w1 map
Run Code Online (Sandbox Code Playgroud)
和get随后是put可以改变的modify,哗众取宠insert.顺便说一句,如果你想知道为什么这Map k a是最后一个参数insert,这就是原因.
ms_assgn (Assgn (Ident ident) exp) = do
w1 <- ms_exp exp
modify $ M.insert ident w1
Run Code Online (Sandbox Code Playgroud)
如果你愿意,你可以确定这两条do线真的只是一条线>>=,所以...
ms_assgn (Assgn (Ident ident) exp) =
ms_exp exp >>= modify . M.insert ident
Run Code Online (Sandbox Code Playgroud)
您可以看到,而不是使用命令式do,数据通过monadic绑定操作符>>=流入修改环境的操作.
| 归档时间: |
|
| 查看次数: |
419 次 |
| 最近记录: |