我在elisp中定义了一个函数来查找向量中列表的索引:
(defun vposition (e v)
(letrec
((f (lambda (e v i)
(if (equal e (elt v i))
i
(f e v (+ i 1))))))
(f e v 0)))
如果我在数字上使用它很好,但是有字符串,例如(vposition "bar" ["foo" "bar" "thing"])
,我收到错误:
Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p "bar")
=("bar" "foo")
如果我这样做,比如(vposition 3 [1 2 3])
,它会按预期工作,而(equal "bar" "foo")
也可以工作,所以我无法隔离问题所在。我错过了什么?
答案 0 :(得分:2)
您的问题是,您对f
的调用不会调用本地变量f
中保存的函数,而是调用之前可能定义的其他函数f
(和该函数使用=
而不是equal
)。当我尝试您的代码和示例时,我得到一个不同的错误:
Symbol's function definition is void: f
您可以使用以下方法轻松修复代码:
(defun vposition (e v)
(letrec
((f (lambda (e v i)
(if (equal e (elt v i))
i
(funcall f e v (+ i 1))))))
(funcall f e v 0)))
当然,这样的递归往往在Elisp中效率低下,因为Elisp实现太天真了,所以你可能想要使用while
循环。
答案 1 :(得分:0)
这个有效:
(defun vposition (e v)
(cl-labels ((f (e v i)
(if (equal e (elt v i))
i
(f e v (+ i 1)))))
(f e v 0)))