我不知道为什么这不起作用。我收到一条错误消息:“错误:1 不是函数 [(anon)]”
(define (mem lst ele)
(cond ;if the list is empty return false
((null? lst) #f)
;if the first element is equal to the given element return true
;otherwise call the function with rest of the list
(else (if (= ele (car lst))
#t
(mem (cdr lst) ele)))))
(mem ’(1) ’(1 4 -2))
答案 0 :(得分:1)
它对我有用;你怎么称呼mem
?我猜你做了类似的事情:(mem (1 2 3 4) 1)
。过程调用总是在 Scheme 中评估它们的参数,因此在过程调用 (mem (1 2 3 4) 1)
中评估表达式 (1 2 3 4)
;但是列表被评估为好像第一个成员是一个过程,所以 1
被视为一个函数;事实并非如此,这引发了一个例外。
您可以引用列表:(mem (quote (1 2 3 4)) 1)
,也可以使用简写(mem '(1 2 3 4) 1)
。 quote
是一种特殊形式,不评估其参数;相反,它只返回给定的任何数据。你可以在 REPL 上试试这个:
> (+ 1 2)
3
> (quote (+ 1 2))
(+ 1 2)
> '(+ 1 2)
(+ 1 2)
此处裸表达式 (+ 1 2)
的计算结果为 3
,但带引号的表达式仅返回赋予 quote
的表达式。也就是说,(quote (+ 1 2))
的计算结果为表达式 (+ 1 2)
,而不是表达式 (+ 1 2)
的计算结果。在 (1 2 3 4)
的情况下:
> (quote (1 2 3 4))
(1 2 3 4)
> '(1 2 3 4)
(1 2 3 4)
> (1 2 3 4)
Exception: attempt to apply non-procedure 1
Type (debug) to enter the debugger.
过程调用 (mem '(1 2 3 4) 1)
将在将该值传递给 '(1 2 3 4)
之前计算表达式 mem
。由于表达式 '(1 2 3 4)
的计算结果为 list,因此该列表是传递给 mem
的值。这与错误调用 (mem (1 2 3 4) 1)
不同,错误调用 (1 2 3 4)
试图通过使用参数 1
、2
调用(不存在的)过程 3
来评估表达式 4
,和list
。
您还可以使用 (mem (list 1 2 3 4) 1)
创建输入:list
。 mem
也是一个过程,因此它评估其参数。这里对 (list 1 2 3 4)
的调用将评估表达式 list
,并且由于 list
是一个过程,因此对 1
的调用将评估参数 2
、{{1 }}、3
和 4
。数字在 Scheme 中是自我评估的,因此对 list
的调用将返回一个列表 (1 2 3 4)
;这个 list 是传递给 mem
的值,它现在已经评估了它的参数 (list 1 2 3 4)
。
cond
形式可以采用多个条件子句,这里没有理由使用 if
。相反,您可以这样做:
(define (mem lst ele)
(cond
((null? lst) #f)
((= ele (car lst)) #t)
(else
(mem (cdr lst) ele))))
=
谓词仅适用于数字;要处理更一般的输入,您可以选择equal?
:
(define (mem lst ele)
(cond
((null? lst) #f)
((equal? ele (car lst)) #t)
(else
(mem (cdr lst) ele))))
现在您可以使用例如符号列表或列表列表:
> (mem '(a b c d) 'c)
#t
> (mem '(a b c d) 'e)
#f
> (mem '(1 (2 3) 4) '(2 3))
#t
> (mem '(1 (2 (3 4)) 5) '(2 (3 4)))
#t
> (mem '(1 (2 3) 4) 3) ;; does not descend into nested lists
#f
请注意,将等式谓词更改为 equal?
将允许在输入列表的顶层搜索列表,但不会更深入。列表(2 (3 4))
可以在列表(1 (2 (3 4)) 5)
中找到,因为它位于列表的顶层,即(2 (3 4))
是列表(1 (2 (3 4)) 5)
的一个元素。但是,(3 4)
不是顶级列表的元素,因此当前的 mem
过程无法在此处找到它。在嵌套列表中搜索需要 mem
的另一个定义。
答案 1 :(得分:0)
您对文字使用了 acute-accent 而不是单引号。
#lang racket
(define (mem ele lst) ;; easier to read with one element -then- list
;; ..plus that's how you wrote your call to it,
;; so this arg-order makes more sense here.
(cond ;; cond doesn't need "else"
((null? lst) #f)
((if (= ele (car lst)) #t
(mem ele (cdr lst)))) ;; element, then list now
)
)
(mem 1 '(1 4 -2))
;; don't know why element needed to be wrapped in a '(1) literal list container
;; also literals require single-quote ' character, not the ’ acute-accent
答案 2 :(得分:0)
从您的示例看来,您正在查找列表 '(1 4 -2)
中的列表 '(1)
,其计算结果为 #f
。但是,您的实现期望所有元素都是数字,因为您与 =
进行比较,这是一个仅数字比较过程。如果你想比较任何类型,你应该使用 equal?
它比较任何类型的两个对象并支持比较结构。