如何解决 lisp 中格式错误的 lambda?
how to solve badly formed lambda in lisp?
我正在尝试用 lisp 检查列表是否有山脉方面。
例如:1,5,9,6,4,3
l 是我的列表,aux 是 0-l 的升序部分或 1-列表的降序部分。
muntemain 只是从 aux=0 开始调用 munte,升序部分
我的错误是:
Badly formed lambda: (AND (< (CAR L) (CAR (CDR L))) (EQ AUX 0))
我看不到problem.Can有人帮忙吗?
(defun munte (l aux)
(cond
((and (atom l) (null aux)) NIL)
((and (null l) (null aux)) NIL)
((and (atom l) (eq aux 1)) T)
((and (null l) (eq aux 1) T)
((and (< (car l) (car(cdr l))) (eq aux 0)) (munte(cdr l) 0))
((and (or (> (car l) (cadr l)) (= (car l) (cadr l))) (eq aux 0))(munte(cdr l) 1))
( and (> (car l) (cadr l)) (eq aux 1)) (munte(cdr l) 1))
(T NIL)
)
)
(defun muntemain (l)
(cond
((> (car l) (cadr l)) NIL)
((< (length l) 2) NIL)
(T (munte l 0))
)
)
正在格式化
作为,你真的需要借助编辑器来帮助你处理括号。安装Emacs+Slime的教程有很多。花点时间安装合适的工具。
不要对数字和字符使用 EQ
An implementation is permitted to make "copies" of characters and
numbers at any time. The effect is that Common Lisp makes no guarantee
that eq is true even when both its arguments are "the same thing" if
that thing is a character or number.
分解测试
((and (atom l) (null aux)) NIL)
((and (null l) (null aux)) NIL)
((and (atom l) (eq aux 1)) T)
((and (null l) (eq aux 1) T)
根据atom
的定义,NIL
是一个原子,所以不需要(null L)
。 aux
的不同情况也可以分组。下面的条款足以说明上述所有内容:
((atom L) (eql aux 1))
但我不明白为什么 aux
如果你总是将它绑定到 0 或 1,那么它首先不是布尔值。只需使用 t
和 nil
和 return aux
在上面的子句中。
使用有意义的函数
(< (car l) (car(cdr l)))
当然,(car(cdr ..))
被称为(cadr ..)
,但也被称为second
。上面的测试相当于:
(< (first L) (second L))
如果您的列表没有第二个元素怎么办?您会将一个数字与 nil
进行比较并发出错误信号(不是您想要的)。你需要更多的测试。在muntemain
中,你似乎有一个长度小于2的特殊情况,但只有在前面的returns nil
时才进行测试,如果错误则不会发生发出信号。
迭代替代
这是一个完全不同的解决问题的方法,只是给你一些想法。
(lambda (list)
(loop
;; memories
for px = nil then x
for pdx = nil then dx
;; current element
for x in list
;; first and second "derivatives" (signs only)
for dx = 1 then (signum (- x px))
for ddx = 0 then (signum (- dx pdx))
;; checks
sum ddx into total
always (and (<= dx 0) (<= -1 total 0))
finally (return (= total -1))))
我正在尝试用 lisp 检查列表是否有山脉方面。 例如:1,5,9,6,4,3
l 是我的列表,aux 是 0-l 的升序部分或 1-列表的降序部分。 muntemain 只是从 aux=0 开始调用 munte,升序部分
我的错误是:
Badly formed lambda: (AND (< (CAR L) (CAR (CDR L))) (EQ AUX 0))
我看不到problem.Can有人帮忙吗?
(defun munte (l aux)
(cond
((and (atom l) (null aux)) NIL)
((and (null l) (null aux)) NIL)
((and (atom l) (eq aux 1)) T)
((and (null l) (eq aux 1) T)
((and (< (car l) (car(cdr l))) (eq aux 0)) (munte(cdr l) 0))
((and (or (> (car l) (cadr l)) (= (car l) (cadr l))) (eq aux 0))(munte(cdr l) 1))
( and (> (car l) (cadr l)) (eq aux 1)) (munte(cdr l) 1))
(T NIL)
)
)
(defun muntemain (l)
(cond
((> (car l) (cadr l)) NIL)
((< (length l) 2) NIL)
(T (munte l 0))
)
)
正在格式化
作为
不要对数字和字符使用 EQ
An implementation is permitted to make "copies" of characters and numbers at any time. The effect is that Common Lisp makes no guarantee that eq is true even when both its arguments are "the same thing" if that thing is a character or number.
分解测试
((and (atom l) (null aux)) NIL)
((and (null l) (null aux)) NIL)
((and (atom l) (eq aux 1)) T)
((and (null l) (eq aux 1) T)
根据atom
的定义,NIL
是一个原子,所以不需要(null L)
。 aux
的不同情况也可以分组。下面的条款足以说明上述所有内容:
((atom L) (eql aux 1))
但我不明白为什么 aux
如果你总是将它绑定到 0 或 1,那么它首先不是布尔值。只需使用 t
和 nil
和 return aux
在上面的子句中。
使用有意义的函数
(< (car l) (car(cdr l)))
当然,(car(cdr ..))
被称为(cadr ..)
,但也被称为second
。上面的测试相当于:
(< (first L) (second L))
如果您的列表没有第二个元素怎么办?您会将一个数字与 nil
进行比较并发出错误信号(不是您想要的)。你需要更多的测试。在muntemain
中,你似乎有一个长度小于2的特殊情况,但只有在前面的returns nil
时才进行测试,如果错误则不会发生发出信号。
迭代替代
这是一个完全不同的解决问题的方法,只是给你一些想法。
(lambda (list)
(loop
;; memories
for px = nil then x
for pdx = nil then dx
;; current element
for x in list
;; first and second "derivatives" (signs only)
for dx = 1 then (signum (- x px))
for ddx = 0 then (signum (- dx pdx))
;; checks
sum ddx into total
always (and (<= dx 0) (<= -1 total 0))
finally (return (= total -1))))