Я сталкивался с той же проблемой, но, возможно, я смогу дать немного больше информации о том, что происходит в моей ситуации, и, возможно, это может помочь.
Создание интерпретатора с помощью typedef:
interp :: Env -> Expr -> M Val
, который обрабатывает циклы в этом формате:
for ( var = expr to expr ) ( expr )
Конструктор данных определен следующим образом:
data Val =
ValInt Int
| ValBool Bool
| ValFun (Val -> M Val)
| ValRecFun (Val -> Val -> M Val)
| ValRef Loc
| ValNil
И расширенная среда определена как:
extendEnv :: Identifier -> Val -> Env -> Env
extendEnv var val (Env bs) = Env ((var,val):bs)
Вот где я нахожусь:
interp env (For x e1 e2 e3) = do
(ValInt v1) <- interp env e1
(ValInt v2) <- interp env e2
if (v1 < v2)
then
let nenv = extendEnv x e1 env in do
interp nenv e3
interp env (For x e1 e2 e3)
else return ValNil
Очевидно, я не хочу передавать "e1" в рекурсивный вызов цикла for, а скорее увеличивать вычисляемую переменную "v1" ..... но я не могу понять, как передать правильное выражение "v1".Достаточно ли этого направления, чтобы получить небольшую помощь? :)
* ОБНОВЛЕНИЕ *
Хорошо, вот моя попытка создать doLoop, который будетделаю мою циклическую работу.Мне кажется, что он немного перегружен, но я не мог понять, как вызвать «env» в doLoop, не передав его в вызове.
interp env (For x e1 e2 e3)= do
(ValInt v1) <- interp env e1
(ValInt v2) <- interp env e2
return doLoop x v1 v2 env e3
doLoop :: Identifier -> Int -> Int -> Env-> Expr -> M Val
doLoop x v1 v2 env e3 =
if v1 > v2 then return ValNil
else
let nenv = extendEnv x (ValInt v1) env in
interp nenv e3
doLoop x (ValInt (v1+1)) v2 nenv e3
ОБНОВЛЕНИЕ
Кажется, у меня возникла проблема с моим определением, а именно:
return doLoop x v1 v2 env e3
Не может соответствоватьожидаемый тип M Val' against my inferred type
Expr -> M Val '.
Я делаю здесь какую-то глупую ошибку?