Почему эта функция вешает REPL?
В главе 9 " Разработка через тестирование с помощью Idris" представлен следующий тип данных и removeElem
функция.
import Data.Vect
data MyElem : a -> Vect k a -> Type where
MyHere : MyElem x (x :: xs)
MyThere : (later : MyElem x xs) -> MyElem x (y :: xs)
-- I slightly modified the definition of this function from the text.
removeElem : (value : a) -> (xs : Vect (S n) a) -> (prf : MyElem value xs) -> Vect n a
removeElem value (value :: ys) MyHere = ys
removeElem value (y :: ys) (MyThere later) = removeElem value (y :: ys) (MyThere later)
Следующие работы:
*lecture> removeElem 1 [1,2,3] MyHere
[2, 3] : Vect 2 Integer
Но следующий вызов все еще выполняется через несколько минут:
*lecture> removeElem 2 [1,2,3] (MyThere MyHere)
Полагаю, почему сборка такая медленная?
1 ответ
Решение
Второй случай вашего removeElem
читает
removeElem value (y :: ys) (MyThere later) = removeElem value (y :: ys) (MyThere later)
Правая сторона точно такая же, как левая; так что ваша рекурсия расходится. Вот почему оценка зависает.
Обратите внимание, что Идрис поймал бы эту ошибку, если бы вы заявили, что removeElem
должно быть общее:
total removeElem : (value : a) -> (xs : Vect (S n) a) -> (prf : MyElem value xs) -> Vect n a
removeElem value (value :: ys) MyHere = ys
removeElem value (y :: ys) (MyThere later) = removeElem value (y :: ys) (MyThere later)
что приводит к ошибке во время компиляции
RemoveElem.idr
строка 9 цв 0:
Main.removeElem
возможно не является полным из-за рекурсивного путиMain.removeElem