Примитивная рекурсия если потом

У меня проблема с проекциями в моем определении "Если потом, остальное". Это на самом деле выполняется как If-Else-Then.

 import Prelude hiding (pred,and,or,not)

 data PR = Z
     | S
     | P Int
     | C PR [PR]
     | PR PR PR
     deriving Show
 eval :: PR -> [Integer] - Integer
 eval Z _ = 0
 eval S [x] = x+1
 eval (P n) xs = nth n xs
 eval (C f gs) xs = eval f (map (\g -> eval g xs) gs)
 eval (PR g h) (0:xs) = eval g xs
 eval (PR g h) (x:xs) = eval h ((x-1) : eval (PR g h) ((x-1):xs) : xs)

 nth _ [] = error "nth nil"
 nth 0 _ = error "nth index"
 nth 1 (x:_) = x
 nth (n) (_:xs) = nth (n-1) xs

 one = C S [Z]
 plus = PR (P 1) (C S [P 2])
 ife = PR (P 1) (C (P 2) [P 3, P 4])

Если я попробую обменяться P 3 а также P 4 он просто полностью разрушается (каждый раз возвращает значение then). ite[0,2,3] должен вернуться 3 а также ite[1,2,3] должен вернуться 2, Вместо этого происходит обратное. Как я могу это исправить?

2 ответа

Решение

Как тебе этот класс? Я заметил вас, и у меня очень похожие домашние задания, очень похожие.

Ну, во-первых, вы хотите создать примитивную рекурсивную функцию, которая имитирует модель IF-Then-Else. следовательно,

eval ite [0,1,2] => 1

а также

eval ite [1,2,3] => 3

и с тем, что вы предоставили, вы, кажется, получаете функцию с теми же качествами, но в противоположных случаях, в зависимости от первого ввода.

ife = PR (P 1) (C (P 2) [P 3, P 4])

Теперь, что ваша функция говорит? ваша реализация ITE использует примитивную рекурсивную конструкцию, это начало, потому что в этом вы можете разделить выполнение на два различных выражения на основе условия. То же условие используется в булевой алгебре. если 0, мы имеем false, в противном случае, если число равно чему-либо (0<), мы имеем true. Конструкция PR делает это, оценивая свой первый аргумент, если заголовок "стека" равен 0, в противном случае он оценивает свой второй аргумент в надежде, что где-то вдоль строки он прекратит работу (часто это время уменьшает голову как ваш счетчик и, в конечном итоге, выполнение первого аргумента). Но для всех намерений и целей мы можем сказать, что второе выражение будет выполнено в (0 <).

Уф! Итак, как мы можем исправить вашу реализацию!? Легко:

ife = PR (P 2) (C (P 1) [P 3, P 4])

Мы переключаем ваши две проекции, так как вы просто сделали их задом наперед. Если заголовок стека Z, мы хотим спроецировать второе выражение, в противном случае мы спроецируем первое. или еще лучше:

ite = PR (P 2) (P 1)

Я думаю, я еще не закончил домашнюю работу, и если я ошибаюсь, я был бы очень признателен за любую дополнительную информацию.

Поскольку я недостаточно хорош, чтобы оставить комментарий, я оставлю его здесь.

Я думаю, что это должно быть

ife = PR (P 1) (C (P 2) [P 3, P 3])
                                ^

вместо оригинальной версии

ife = PR (P 1) (C (P 2) [P 3, P 4])
                                ^

Таким образом, X будет выбран, если первое значение не равно 0 Иначе Y. Таким образом, случайные значения не возвращаются. Также это делает написание и / или /... легче.

Другие вопросы по тегам