List 我定义的cond函数工作不正常(LISP)
我试图定义我自己的函数,使我的hw2更容易,但它不工作。你能看一下,告诉我我遗漏了什么吗List 我定义的cond函数工作不正常(LISP),list,lisp,common-lisp,atomic,conditional-statements,List,Lisp,Common Lisp,Atomic,Conditional Statements,我试图定义我自己的函数,使我的hw2更容易,但它不工作。你能看一下,告诉我我遗漏了什么吗 (DEFUN testAL(x) COND ( ( ATOMP(x) ) 'this-is-an-atom ) ( ( LISTP(x) ) 'this-is-a-list ) ( T 'this-is-neither ) ) 如果这个条件函数是atom、list或两者都不是,我希望它接受输入X和输出。问题是,当我输入NIL时,我
(DEFUN testAL(x)
COND ( ( ATOMP(x) ) 'this-is-an-atom )
( ( LISTP(x) ) 'this-is-a-list )
( T 'this-is-neither ) )
如果这个条件函数是atom、list或两者都不是,我希望它接受输入X和输出。问题是,当我输入NIL时,我得到一个错误:尝试获取未绑定变量“COND”的值
家庭作业2包括以下问题:
下列哪一项是原子,哪一项列出,哪一项和哪一项都不是
a。零
b。(出口103)
c。(a)b)
d。六十四
e。T
f。(没有比家更好的地方了)
g、 "(+356)
括号的位置不正确。除非带引号,否则括号是函数应用程序的开始 它以一个未绑定的变量
cond
开始。它不是特殊形式的(cond(谓词结果)(谓词2结果))
,因为它不是以开括号开头的
仅从缩进来看,我想你是想写:
(DEFUN testAL (x)
(COND ((ATOM x) 'this-is-an-atom)
((LISTP x) 'this-is-a-list)
(T 'this-is-neither)))
(testal 'test) ; ==> THIS-IS-AN-ATOM
(testal '(a b c)) ; ==> THIS-IS-A-LIST
由于(x)
表示应用函数x
,而x
表示变量x,因此我删除了x
周围的额外括号。如果x
位于不同的位置,如(+x3)
,则+
是要应用的函数,x
是其操作数之一
我将atomp
更改为atom
。由于atom
是50年代第一个用LISP定义的最早的原语之一,它不像大多数其他谓词那样有后缀p
编辑:多重匹配
你可以有几个cond
(或者if
,因为每个测试只有一个),并且做一些副作用,比如(打印“THIS-IS-a-ATOM”)
,因为你的基本情况永远不会触发(在CL中没有任何东西既不是列表也不是原子)。这也许是最简单的解决办法
(DEFUN testAL (x)
(if (ATOM x) (print 'this-is-an-atom))
(if (LISTP x) (print 'this-is-a-list)))
(testal '()) ; ==> THIS-IS-A-LIST (but prints both)
对于更功能化的方法,我会使用更高阶的函数来保持代码的可测试性,并提供一个打印函数来消除副作用。请注意,对于初学者来说,这可能不那么容易阅读:
;; a list of pairs of predicate and their desription
(defparameter *type-predicates-and-description*
'((douglasp . this-is-the-answer-to-everything)
(floatp . this-is-a-floating-pont-number)
(integerp . this-is-an-integer)
(numberp . this-is-a-number)
(null . this-is-null)
(listp . this-is-a-list)
(characterp . this-is-a-character)
(stringp . this-is-a-string)))
;; custom made predicate
(defun douglasp (x)
(and (numberp x) (= x 42)))
;; returns all the types of a particular value
(defun get-type-info (x)
"return a list if types thet describes argument"
(flet ((check-type (acc type-pair)
"Accumulate description when predicate match"
(if (funcall (car type-pair) x)
(cons (cdr type-pair) acc)
acc)))
;; test x for each type predicate-description
(let ((res (reduce #'check-type
*type-predicates-and-description*
:initial-value '())))
;; check of empty list (no types matched)
(if (null res)
(list 'this-is-neither)
res))))
;; test it
(get-type-info '()) ; ==> (THIS-IS-A-LIST THIS-IS-NULL)
(get-type-info 42) ; ==> (THIS-IS-A-NUMBER
; THIS-IS-AN-INTEGER
; THIS-IS-THE-ANSWER-TO-EVERYTHING)
(get-type-info #()) ; ==> (THIS-IS-NEITHER)
;; Make a function to do side effects
(defun print-type-info (x)
(format t "~{~a~^, ~}." (get-type-info x)))
(print-type-info '()) ; ==> NIL
; and prints "THIS-IS-A-LIST, THIS-IS-NULL."
括号的位置不正确。除非带引号,否则括号是函数应用程序的开始
它以一个未绑定的变量cond
开始。它不是特殊形式的(cond(谓词结果)(谓词2结果))
,因为它不是以开括号开头的
仅从缩进来看,我想你是想写:
(DEFUN testAL (x)
(COND ((ATOM x) 'this-is-an-atom)
((LISTP x) 'this-is-a-list)
(T 'this-is-neither)))
(testal 'test) ; ==> THIS-IS-AN-ATOM
(testal '(a b c)) ; ==> THIS-IS-A-LIST
由于(x)
表示应用函数x
,而x
表示变量x,因此我删除了x
周围的额外括号。如果x
位于不同的位置,如(+x3)
,则+
是要应用的函数,x
是其操作数之一
我将atomp
更改为atom
。由于atom
是50年代第一个用LISP定义的最早的原语之一,它不像大多数其他谓词那样有后缀p
编辑:多重匹配
你可以有几个cond
(或者if
,因为每个测试只有一个),并且做一些副作用,比如(打印“THIS-IS-a-ATOM”)
,因为你的基本情况永远不会触发(在CL中没有任何东西既不是列表也不是原子)。这也许是最简单的解决办法
(DEFUN testAL (x)
(if (ATOM x) (print 'this-is-an-atom))
(if (LISTP x) (print 'this-is-a-list)))
(testal '()) ; ==> THIS-IS-A-LIST (but prints both)
对于更功能化的方法,我会使用更高阶的函数来保持代码的可测试性,并提供一个打印函数来消除副作用。请注意,对于初学者来说,这可能不那么容易阅读:
;; a list of pairs of predicate and their desription
(defparameter *type-predicates-and-description*
'((douglasp . this-is-the-answer-to-everything)
(floatp . this-is-a-floating-pont-number)
(integerp . this-is-an-integer)
(numberp . this-is-a-number)
(null . this-is-null)
(listp . this-is-a-list)
(characterp . this-is-a-character)
(stringp . this-is-a-string)))
;; custom made predicate
(defun douglasp (x)
(and (numberp x) (= x 42)))
;; returns all the types of a particular value
(defun get-type-info (x)
"return a list if types thet describes argument"
(flet ((check-type (acc type-pair)
"Accumulate description when predicate match"
(if (funcall (car type-pair) x)
(cons (cdr type-pair) acc)
acc)))
;; test x for each type predicate-description
(let ((res (reduce #'check-type
*type-predicates-and-description*
:initial-value '())))
;; check of empty list (no types matched)
(if (null res)
(list 'this-is-neither)
res))))
;; test it
(get-type-info '()) ; ==> (THIS-IS-A-LIST THIS-IS-NULL)
(get-type-info 42) ; ==> (THIS-IS-A-NUMBER
; THIS-IS-AN-INTEGER
; THIS-IS-THE-ANSWER-TO-EVERYTHING)
(get-type-info #()) ; ==> (THIS-IS-NEITHER)
;; Make a function to do side effects
(defun print-type-info (x)
(format t "~{~a~^, ~}." (get-type-info x)))
(print-type-info '()) ; ==> NIL
; and prints "THIS-IS-A-LIST, THIS-IS-NULL."
什么是hw2?“这将如何使它更容易?”约书亚泰勒说,从技术上讲,这将是更多的工作,但我正在努力学习语言。我在上面的问题中添加了hw2。什么是hw2?“这将如何使它更容易?”约书亚泰勒说,从技术上讲,这将是更多的工作,但我正在努力学习语言。我已经在上面的问题中添加了hw2。我知道我错在哪里了。使用额外的括号可以很好地工作。我有一个后续问题。COND的工作方式类似于switch语句,在java上每个case上都有“break”。我希望COND能够遍历每一行,不管它是否为真,并打印每一行为真。例如,如果我这样做(testal'NIL),它会打印“这是一个原子”和“这是一个列表”,但它会在第一个T条件下停止。我的问题是:COND有没有一种方法可以将X与每个条件进行比较,而不暂停它找到的第一个T?@rtrigoso我在我的答案中添加了一些关于几个答案的想法。我明白了,因此通过使用多个COND,或者在本例中为IFs,不会跳过不存在的情况下的打印输出?谢谢,我知道我错在哪里了。使用额外的括号可以很好地工作。我有一个后续问题。COND的工作方式类似于switch语句,在java上每个case上都有“break”。我希望COND能够遍历每一行,不管它是否为真,并打印每一行为真。例如,如果我这样做(testal'NIL),它会打印“这是一个原子”和“这是一个列表”,但它会在第一个T条件下停止。我的问题是:COND有没有一种方法可以将X与每个条件进行比较,而不暂停它找到的第一个T?@rtrigoso我在我的答案中添加了一些关于几个答案的想法。我明白了,因此通过使用多个COND,或者在本例中为IFs,不会跳过不存在的情况下的打印输出?谢谢