【问题标题】:Haskell: define interpreter for languageHaskell:为语言定义解释器
【发布时间】:2016-10-02 09:17:43
【问题描述】:

作为定义语言解释器的一部分,我有以下定义:

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)

【问题讨论】:

  • 这是一个让你得到 A、B、C 并告诉你去实现 X、Y、Z 的练习吗?还是你自己设计整个东西?
  • @MathematicalOrchid 这是一个练习,是的
  • 你能具体告诉我们你得到了哪些比特,它们应该是什么意思吗? (例如,看起来 Context 是一对地图 - 但这些地图应该表示是什么意思?:+: 来自哪里?)
  • 公平地说,“编写解释器”将是 C# 或 Java 中的一项重大任务。但在 Haskell 中,这是一个小的初学者练习。也许 是人们认为 Haskell 是一种“硬语言”的原因。 ;-)
  • 如果(+)在环境中,您可能需要定义evalExpr (e1 :+: e2),而不是使用Haskell +,而是从环境中获取+的含义。所以,像Intepreter $ \ctx -&gt; let plus = lookupEnv ctx "+" in ... 这样的自定义lookupEnv。您还需要将函数添加到您的值中。

标签: haskell interpreter


【解决方案1】:

好的,我会尝试一下...

所以看起来Context 由一对映射组成。似乎第一个映射允许您从变量的名称中查找变量的值。第二个可以让你查找一个函数名并获得它对应的可执行代码。

你使用Interpreter 就好像它是一个单子;我不知道是不是真的,但看起来很合理。

所以initCtx 开始时没有定义任何变量 (Map.empty),大概你打算在第二个映射中放置一堆预定义函数,如 +

查看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 会发生什么?就此而言,如果有人用不同数量的参数调用“+”怎么办?我们需要在这里进行一些错误检查。

猜测您正在寻找的东西可能看起来像这样:

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."

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-28
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    相关资源
    最近更新 更多