member

gosh> (member 'cookie *inventory*)
(cokkie dagger)
gosh> (member 'ration *inventory*)
#f

のように、第1引数を第2引数の中から探し、見つかった場合には見つけたものを含めた残りのリストを、見つからなかったら#fを返す。
つまり、ifなどの条件式に使える。
同じかどうかの判定にはequal?が使用されるが、

(use srfi-1)

しとけば、3つ目の引数で等価述語を指定できる。


memberを自前で定義すると

(define my-member
  (lambda (elt lis . optionals)
    (let-optionals* optionals ((cmp-fn equal?))
      (cond
        ((null? lis) #f)
        ((cmp-fn elt (car lis)) lis)
        (else (my-member elt (cdr lis) cmp-fn))))))

だけど、省略可能引数の名前束縛が毎回行われて効率がわるいらしい。

(define my-member
  (lambda (elt lis . optionals)
    (let-optionals* optionals ((cmp-fn equal?))
      (define loop
        (lambda (lis)
          (cond
            ((null? lis) '())
            ((cmp-fn elt (car lis)) lis)
            (else (loop (cdr lis))))))
      (loop lis))))

ってすると、lisがめっちゃ長いときに違いが出てくるんだって!


アイテムが*inventory*にあるかどうかは

(define has-item?
  (lambda (item)
    (member item *imventory*)))

って手続きで調べられるよねー、と。