2013-09-21 2 views
0

Я определил функцию в 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") работ, тоже, так что я не могу выделить, где проблема. Что мне не хватает?

ответ

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.

+0

Действительно тщательный ответ - спасибо! – amindfv

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))) 
+0

Где '' 'cl-labels''' определен? Это не в '' 'cl'''. Кроме того, есть ли причина '' 'letrec''' ломаться, а' '' cl-labels''' нет? – amindfv

+0

Файл 'cl-macs.el', но вы получите его с помощью' (require 'cl-lib) '. 'cl-lib' - это вкусный способ использования cl в Emacs, я думаю. –

Смежные вопросы