2012-06-12 2 views
2

У меня возникли проблемы с попыткой включить инструкцию чтения и записи в функцию evaluateStatementInner.Haskell Recursive IO

Я попытался изменить типы возврата обеих функций без успеха.

Я пытаюсь преобразовать тип IO(Env) в Env. Я знаю, что это можно сделать с привязкой к функции, которая возвращает действие IO, но могу ли я сделать это в операторе evaluateInner?

Приветствия

+0

Не ссылайтесь на внешний код, извлекайте только то, что необходимо для понимания и ответа, и вместо этого помещайте его в свой вопрос. У вас будет гораздо больше шансов получить помощь;) –

+0

Спасибо, сейчас. – user1424720

+0

Я думаю, вы не можете выполнять функцию «Чистая функция, вызывающая функцию Impure (IO)», тогда как обратное верно. – Ankur

ответ

4

оценки Read и Write необходимостью включает в себя выполнение ввода/вывода. Поэтому укусите пулю и измените тип evaluateStatementInner на Stmt -> Env -> IO Env (или, лучше, включите его непосредственно в evaluateStatement).

Затем вам необходимо будет изменить evaluateListOfStatements на тип [Stmt] -> Env -> IO Env.


Так что теперь дает вам ошибку компиляции

case stmt of 
... 
    While boolExp innerStmt -> 
     if evaluateBoolExp boolExp env 
      then evaluateStatementInner (While boolExp innerStmt) (evaluateStatementInner innerStmt env) 
      else env 

потому что evaluateStatementInner innerStmt env дает IO Env, но evaluateStatementInner (While boolExp innerStmt) хочет Env.

Это случай для монадического связывания (и обратите внимание потребность еще ветви обновления, чтобы иметь правильный тип, а):

case stmt of 
... 
    While boolExp innerStmt -> 
     if evaluateBoolExp boolExp env 
      then evaluateStatementInner (While boolExp innerStmt) =<< evaluateStatementInner innerStmt env 
      else return env 

Вы не мог бы быть комфортно с монадическими операторами, так что я буду переводить Это не обязательно:

case stmt of 
... 
    While boolExp innerStmt -> 
     if evaluateBoolExp boolExp env 
      then do env' <- evaluateStatementInner innerStmt env 
        evaluateStatementInner (While boolExp innerStmt) env' 
      else return env 
+0

Я пробовал это, но я получаю ошибку компиляции в этой строке: «then оценитеStatementInner (While boolExp innerStmt) (оценкаStatementInner innerStmt env)», где он говорит, что ожидаемый тип Env, но фактический тип - IO (Env). Это то, о чем я говорил в другом комментарии. – user1424720

+0

@ user1424720 См. Мое редактирование. – dave4420

+0

Спасибо, сработало. Возможно, я должен был попасть в Haskell немного раньше, чем начать этот проект. Как только я закончил, я прочитал о монадических операторах. – user1424720