Как привести монадического переводчика в монаду IO? - PullRequest
0 голосов
/ 01 января 2019

Мой вопрос касается простого переводчика, написанного в в этом ответе .Я уже задавал аналогичный вопрос до , который относится к первому не монадическому интерпретатору в ответе за ссылкой.Но есть второй монадический , к которому относится этот вопрос .

Как можно добавить возможности ввода-вывода к монадическому интерпретатору ( Вам необходимо прокрутить вниз , потому что ответ содержит два варианта, первый из которых не является монадическим, а второй - монадическим .)?Под этим я просто подразумеваю добавление оператора, который использует putStrLn.Я еще не очень хорошо разбираюсь в Хаскеле, но, полагаю, вы можете как-то объединить монаду ввода-вывода и монаду интерпретатора.Может ли кто-нибудь указать мне правильное направление?

data Stmt
  = Var := Exp                                   
  | While Exp Stmt                                               
  | Seq [Stmt]      
  | Print Exp       -- a print statement

1 Ответ

0 голосов
/ 03 января 2019

Простым подходом является изменение Interp для включения IO.

newtype Interp a = Interp { runInterp :: Store -> IO (Either String (a, Store)) }

Тогда нам просто нужно обновить Monad экземпляр, rd, wr и run для новых внутренних элементов Interp путем разбрызгивания в некоторых return с и связывания.Например, вот новый экземпляр Monad:

instance Monad Interp where
  return x = Interp $ \r -> return (Right (x, r))
  i >>= k =
    Interp $ \r -> do
      res <- runInterp i r
      case res of
        Left msg -> return (Left msg)
        Right (x, r') -> runInterp (k x) r'
  fail msg = Interp $ \_ -> return (Left msg)

Одним из преимуществ абстрагирования Interp в первую очередь было то, что мы можем вносить подобные изменения без изменения основной части.переводчика (eval и exec) вообще.

...