2016-10-02 2 views
0

В рамках определения интерпретатора языка у меня есть следующее определение:Haskell: определить интерпретатор для языка

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, мне практически необходимо иметь дело с этим.

Спасибо!

EDIT:

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

Это упражнение, где вы получили A, B, C и сказали идти реализовать X , Y, Z? Или вы сами разрабатываете все это? – MathematicalOrchid

+0

@MathematicsOrchid это упражнение, да – Comforse

+0

Можете ли вы рассказать нам конкретно, какие биты вам даны и что они должны означать? (Например, «Контекст» - это пара карт, но что означает эти карты, которые должны означать *? Где: ': +:' из?? – MathematicalOrchid

ответ

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." 
Смежные вопросы