Functional programming 球拍-构建内置的成员功能

Functional programming 球拍-构建内置的成员功能,functional-programming,lisp,racket,sicp,Functional Programming,Lisp,Racket,Sicp,我喜欢编写与内置函数相同的代码。这对我来说总是一个很好的锻炼 在racket中有一个名为“member”的bult-In函数,用于检查某个元素是否在列表中。如果为true,则函数返回列表的rest/cdr;如果为false,则函数返回#f。示例: > (member 2 (list 1 2 3 4)) '(2 3 4) > (member 9 (list 1 2 3 4)) #f 我执行了以下代码: (require racket/trace) (define (member-

我喜欢编写与内置函数相同的代码。这对我来说总是一个很好的锻炼

在racket中有一个名为“member”的bult-In函数,用于检查某个元素是否在列表中。如果为true,则函数返回列表的rest/cdr;如果为false,则函数返回#f。示例:

> (member 2 (list 1 2 3 4))
'(2 3 4)

> (member 9 (list 1 2 3 4))
#f
我执行了以下代码:

(require racket/trace)

(define (member-mine lista num)
  (cond ((equal? (car lista) num) (cdr lista))
        ((equal? (car lista) '()) #f)
        (else (member-mine (cdr lista) num))))

(define small-list (list 1 2 3 4 5 6 7 8))

(trace member-mine)
而且,当我尝试将它与酷工具跟踪一起使用时,我取得了部分成功

电话:

(member-mine small-list 1)
(member-mine small-list 8)
返回:

>(member-mine '(1 2 3 4 5 6 7 8) 1)
<'(2 3 4 5 6 7 8)
>(member-mine '(1 2 3 4 5 6 7 8) 8)
>(member-mine '(2 3 4 5 6 7 8) 8)
>(member-mine '(3 4 5 6 7 8) 8)
>(member-mine '(4 5 6 7 8) 8)
>(member-mine '(5 6 7 8) 8)
>(member-mine '(6 7 8) 8)
>(member-mine '(7 8) 8)
>(member-mine '(8) 8)
<'()
返回:

>(member-mine '(1 2 3 4 5 6 7 8) 1)
<'(2 3 4 5 6 7 8)
>(member-mine '(1 2 3 4 5 6 7 8) 8)
>(member-mine '(2 3 4 5 6 7 8) 8)
>(member-mine '(3 4 5 6 7 8) 8)
>(member-mine '(4 5 6 7 8) 8)
>(member-mine '(5 6 7 8) 8)
>(member-mine '(6 7 8) 8)
>(member-mine '(7 8) 8)
>(member-mine '(8) 8)
<'()
返回的是一个错误:

>(member-mine '(1 2 3 4 5 6 7 8) 9)
>(member-mine '(2 3 4 5 6 7 8) 9)
>(member-mine '(3 4 5 6 7 8) 9)
>(member-mine '(4 5 6 7 8) 9)
>(member-mine '(5 6 7 8) 9)
>(member-mine '(6 7 8) 9)
>(member-mine '(7 8) 9)
>(member-mine '(8) 9)
>(member-mine '() 9)
. . car: contract violation
  expected: pair?
  given: '()

如何处理空的?

将空的大小写移动为条件的第一个分支。当在最后一次递归调用中将空列表传递到函数中时,您会请求列表的
car
,因为列表是空的,所以无法执行此操作。在调用
car

之前,先放置空的case应该会导致函数以
#f
终止。作为第一个观察,您已切换合同,以便列表位于第一位而不是最后一位

您似乎还在检查其中一个元素是否为空列表,而不是列表本身。因此,在这种情况下,您的
成员将以
#f
终止:

(member-mine '(() 1 2 3 4 5 6 7 8) 1) ; ==> #f
因此,您的成员应该检查整个参数是否为
null?
空?
),或者检查它是否为
对?
。然后它应该计算为
#f


如果第一个元素与您的搜索相匹配,则原始
成员将以匹配作为第一个元素而不是代码中类似的
cdr
计算整个参数。

检查空列表的另一种方法是检查其长度:

(define (member-mine lista num)
  (cond
    ((equal? (length lista) 0) #f)    ; '=' can also be used instead of 'equal?'
    ((equal? (car lista) num) (cdr lista))
    (else (member-mine (cdr lista) num))))

(define small-list (list 1 2 3 4 5 6 7 8))

(member-mine small-list 9)
输出:

#f
但正确的方法是:

(empty? lista)  or (null? lista)

谢谢它起作用了:(定义(成员mine lista num)(cond((empty?lista)#f)((equal?(car lista)num)(cdr lista))(else(成员mine(cdr lista)num))),但是有没有其他方法来处理空的?不确定。据我所知,空情况是确保正确终止的唯一方法,因为它是递归函数的基本情况。