оценки 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
Не ссылайтесь на внешний код, извлекайте только то, что необходимо для понимания и ответа, и вместо этого помещайте его в свой вопрос. У вас будет гораздо больше шансов получить помощь;) –
Спасибо, сейчас. – user1424720
Я думаю, вы не можете выполнять функцию «Чистая функция, вызывающая функцию Impure (IO)», тогда как обратное верно. – Ankur