公共Lisp类型检查两个变量
嗨,我是一个普通口齿不清的初学者。我想检查两个变量是否是整数。如果n和m都是整数,我希望它返回公共Lisp类型检查两个变量,lisp,common-lisp,Lisp,Common Lisp,嗨,我是一个普通口齿不清的初学者。我想检查两个变量是否是整数。如果n和m都是整数,我希望它返回-如果它是负数,0如果它是零,+如果它是正数,NIL如果它不是n和m的整数。我知道如何用一个变量来实现这一点,但我似乎不知道如何用两个变量来实现这一点。谢谢 这是一段代码,它接受一个数值参数,如果它为负,则返回-;如果它为零,则返回0;如果它为正,则返回+;如果它不是整数,则返回NIL: (defun sign (n) (if(typep n 'integer) (cond ((< n
-
如果它是负数,0
如果它是零,+
如果它是正数,NIL
如果它不是n和m的整数。我知道如何用一个变量来实现这一点,但我似乎不知道如何用两个变量来实现这一点。谢谢
这是一段代码,它接受一个数值参数,如果它为负,则返回-
;如果它为零,则返回0
;如果它为正,则返回+
;如果它不是整数,则返回NIL
:
(defun sign (n)
(if(typep n 'integer)
(cond ((< n 0) '-)
((= n 0) 0)
((> n 0) '+))))
这是我用来检查两个变量的代码,我想让它检查n和m是整数,n和m是正的、负的还是零:
(defun sign (n m)
(if (and (typep n 'integer) (typep m 'integer))
(cond (and ((< n 0) '-) ((< m 0) '-))
(and ((= n 0) 0) ((= m 0) 0))
(and ((> n 0) '+) ((> m 0) '+)) ))))
(除符号(n m)
(if(and(typep n'整数)(typep m'整数))
(第(和(n0)+(>m0)+))
看起来您的方法是正确的,只是在括号中迷失了方向。您的每个cond
案例
(and ((< n 0) '-) ((< m 0) '-))
(和(
我想你是说
((and (< n 0) (< m 0)) '-)
((和(
另外两种情况也是一样。记住基本的Lisp语法。函数调用和一些基本表达式编写为
(operator argument-0 argument-1 ... argument-n)
对吧?
开括号,运算符,参数-0参数-1。。。参数-n,右括号
现在,如果我们有(
和(
表达式会是什么样子
(and (< n 0) (< m 0))
所以不是
(defun sign (n m)
(if (and (typep n 'integer) (typep m 'integer))
(cond (and ((< n 0) '-) ((< m 0) '-))
(and ((= n 0) 0) ((= m 0) 0))
(and ((> n 0) '+) ((> m 0) '+)))))
(除符号(n m)
(if(and(typep n'整数)(typep m'整数))
(第(和(n0)+(>m0)+)))
顺便说一句,结尾有一个额外的括号
我们写道:
(defun sign (n m)
(if (and (typep n 'integer) (typep m 'integer))
(cond ((and (< n 0) (< m 0)) '-)
.... )))
(除符号(n m)
(if(and(typep n'整数)(typep m'整数))
(cond((和(
还可以使用诸如
integerp
、minssp
、zerop
和plusp
之类的谓词。您可以使用已经运行并经过测试的符号
定义,这是lispers程序的典型方式。第一个简单的解决方案是:
(defun sign-for-two (n m)
(when (eql (sign n) (sign m))
(sign n))
;; (if (condition) return-value NIL)
;; is equivalent to
;; (when (condition) return-value)
注意,在common lisp中,这一点很重要,
您选择的平等性测试:
;; only symbols - for object identity eq
;; symbols or numbers - for object identity eql
;; (in most tests the default)
;; eql for each component? also in lists equal
;; equal not only lists but also
;; arrays (vectors, strings), structures, hash-tables
;; however case-insensitive in case of strings
;; equalp
;; mathematical number equality =
;; specifically characters char=
;; case-sensitive string equality string=
在我们的例子中,eql就足够了
;; to avoid `(sign n)` to be evaluated twice,
;; you could store it using `let`
;; and call from then on the stored value
;; (which is less costly).
(defun sign-for-two (n m)
(let ((x (sign n)))
(when (eql x (sign m))
x)))
或者创建一个相等性测试仪(默认测试函数:#'eql
)
它返回相同的测试值
如果不相等,NIL
:
(defun equality-value (x y &key (test #'eql))
(when (funcall test z y) z)))
;; and apply this general solution to our case:
(defun sign-for-two (n m)
(equality-value (sign n) (sign m)))
您可以应用相等值
函数
在将来的函数中
测试为“相等”时返回值
您可以通过:test
任何等式给出函数
除了eql
之外的函数适用于这种情况,如
(equality-value string1 string2 :test #'string=)
另一种编写
符号的简洁方法是使用标准函数
根据数字是否为负数返回-1、0或1中的一个,
零,还是正
代码可能如下所示:
(defun sign (n)
(when (integerp n)
(case (signum n)
(-1 '-)
(0 0)
(1 '+))))
let
内部的相等值
不是必需的,但更重要的是,调用test
应该使用funcall完成。@coredump啊,谢谢你-我总是喜欢你的答案和评论我在控制台上更正了这个(funcall),但忘了在文本中更正它。诚然,let inside相等值是多余的-我将删除它。我对以前的代码:D考虑得太多了。
(defun equality-value (x y &key (test #'eql))
(when (funcall test z y) z)))
;; and apply this general solution to our case:
(defun sign-for-two (n m)
(equality-value (sign n) (sign m)))
(equality-value string1 string2 :test #'string=)
(defun sign (n)
(when (integerp n)
(case (signum n)
(-1 '-)
(0 0)
(1 '+))))