作为定义语言解释器的一部分,我有以下定义:
initCtx :: Context
initCtx = (Map.empty, initEnv)
where initEnv =
Map.fromList [ ...
, ("+", undefined)
...
]
对于总和操作,我有这个:
evalExpr :: Expr -> Interpreter Value
evalExpr (e1 :+: e2) = do v1 <- eval e1
v2 <- eval e2
return Interpreter $ (v1 + v2)
exalExpr是由我创建的,但是我需要编写什么来代替undefined
以便执行表达式?或者,也许,我正在寻找错误的东西?我当然有更多的操作,但我只需要一个例子。我是Haskell的新手,我几乎需要处理它。
谢谢!
修改
type Env = Map Ident Value
type Primitive = [Value] -> Interpreter Value
type PEnv = Map FunName Primitive
type Context = (Env, PEnv)
这是Expr
:
data Expr = Number Int
| String String
| Array [Expr]
| Undefined
| TrueConst
| FalseConst
| Var Ident
| Compr ArrayFor Expr
| Call FunName [Expr]
| Assign Ident Expr
| Comma Expr Expr
deriving (Eq, Read, Show)
Interpreter
newtype Interpreter a = Interpreter {runInterpreter :: Context -> Either Error (a, Env)}
和价值:
data Value = IntVal Int
| UndefinedVal
| TrueVal | FalseVal
| StringVal String
| ArrayVal [Value]
deriving (Eq, Show)
答案 0 :(得分:1)
好吧,我会捅这个...
所以看起来Context
由一对地图组成。看来第一张地图可让您从名称中查找变量的值。第二个允许您查找函数名称并获取相应的可执行代码。
您正在使用Interpreter
,好像它是一个monad;我不知道它是否确实存在,但看起来似乎有道理。
所以initCtx
开始时没有定义任何变量(Map.empty
),并且可能你想在第二张地图中放置一堆预定义函数,例如+
。< / p>
查看Primitive
的定义,它会获取Value
的列表并返回Interpreter
次计算。所以我猜它看起来像
addExpr :: [Value] -> Interpreter Value
addExpr [e1, e2] = do
v1 <- eval e1
v2 <- eval e2
return (v1 + v2)
然后你可以写map.fromList [... ("+", addExpr) ...]
。
除此之外也不太正确。 Value
不是数字类型;如果,例如,v1 = StringVal
会发生什么?就此而言,如果有人打电话给&#34; +&#34;有不同数量的参数?我们需要在这里进行一些错误检查。
我猜测您正在寻找的东西可能看起来像这样:
checkInt :: Value -> Interpreter Int
checkInt (IntVal x) = return x
checkInt _ = Interpreter $ ctx -> Left "Not an integer."
addExpr :: [Value] -> Interpreter Value
addExpr [expr1, expr2] do
val1 <- eval expr1
int1 <- checkInt val1
val2 <- eval expr2
int2 <- checkInt val2
return (IntVal $ int1 + int2)
addExpr _ = Interpreter $ ctx -> error "Wrong number of arguments."