Yet Another Common Lisp Problems #1 singlep

なんか見つけたので気が向いた時に解いていってみよう。

●問題1

リストの要素がただひとつか調べる述語 singlep を定義してください。

> (singlep '(a))
t
> (singlep '(a b))
nil
> (singlep '())
nil

解答

ホームページ移転のお知らせ - Yahoo!ジオシティーズ

とりあえず On Lisp あたりで読んだような気がした実装。

(defun singlep (list)
  (and (consp list) (endp (cdr list))))

consp は nil には nil を返す(時々忘れててハマる)。
endp は null でも (eql ... nil) とかしてもいいんだけどせっかくなので使ってみた。と思って調べてみたらちょっと違ったようだ。

null と異なり、例えば文字列を指定するとエラーを発生します。

http://xyzzy.s53.xrea.com/reference/wiki.cgi?p=endp

ということは dotted-list だと結果が変わる。

(defun singlep-with-endp (list)
  (and (consp list) (endp (cdr list))))
=> singlep-with-endp

(defun singlep-with-null (list)
  (and (consp list) (null (cdr list))))
=> singlep-with-null

(singlep-with-endp '(a . b))
; Evaluation aborted on `type-error'
;   不正なデータ型です: b: list

(singlep-with-null '(a . b))
=> nil

predicate function って「与えられた値が特定の条件を満たす場合は non-nil を、満たさなければ nil を返す」ものだと思うので null を使った方が良いよね。ということで。

(defun singlep (list)
  (and (consp list) (null (cdr list))))
=> singlep