Recursion 为什么这个函数会挂起REPL?

Recursion 为什么这个函数会挂起REPL?,recursion,idris,partial-functions,totality,Recursion,Idris,Partial Functions,Totality,的第9章介绍了以下数据类型和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

的第9章介绍了以下数据类型和
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)

我想,为什么编译这么慢?

您的
removeElem的第二个案例是

removeElem value (y :: ys)    (MyThere later) = removeElem value (y :: ys) (MyThere later)
右侧与左侧完全相同;所以你的递归发散了。这就是评估挂起的原因

请注意,如果您声明
removeElem
应为total,Idris将捕获此错误:

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)
这会导致编译时错误

removelem.idr
第9行第0列:

Main.removeElem
可能由于递归路径
Main.removeElem


我意识到“我将如何修复
removeElem
的定义”中有一个明显的后续问题,但既然您正在学习,我想您应该先自己尝试解决它。谢谢。“unfounded”是什么意思?我最初的意思是递归没有很好的基础。但是现在我想起来了,也许这里使用的术语是错误的……我已经稍微更新了我的答案,希望能让它更清楚。您可以通过在模块中添加
%default total
使
成为默认值(然后您需要用
partial
标记部分函数)。至于你的问题,如果你正在定义一个非total函数,你就不会使用
total
,当然:)有一些很好的程序示例,这些程序都是
total
,只有一个
部分定义允许服务器无限期地接受新请求。其思想是,所有其他函数的
总数
可以确保在有限的时间内处理任何给定的请求