Recursion 为什么这个函数会挂起REPL?
的第9章介绍了以下数据类型和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
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
,只有一个部分定义允许服务器无限期地接受新请求。其思想是,所有其他函数的总数可以确保在有限的时间内处理任何给定的请求