The King's Museum

ソフトウェアエンジニアのブログ。

『Scheme 手習い』はじめました。

Gauche 本を進めていたけれど、なんだかあんまり身についてる気がしなかったので『Scheme 手習い』に手を出してみた

Scheme手習い

Scheme手習い

  • 作者: Daniel P. Friedman,Matthias Felleisen,元吉文男,横山晶一
  • 出版社/メーカー: オーム社
  • 発売日: 2010/10/22
  • メディア: 単行本(ソフトカバー)
  • 購入: 5人 クリック: 129回
  • この商品を含むブログ (34件) を見る

第1章:おもちゃ

アトム、リスト、S 式とは

Gauche は atom? が定義されてないので、本に書いてあるように定義する。

(define atom?
  (lambda (x)
    (and (not (pair? x)) (not (null? x)))))

(atom? '0) ; => #t

「(atom? '0) が #f になることを確かめてほしい」って本に書いてあるけど、おかしい…。 本の誤植かも。

(atom? 'atom) ; => #t
(atom? 1492) ; => #t
(atom? '()) ; => #f
(atom? '(1 2 3)) ; => #f

アトムはリストではないもの。

(list? 'atom) ; => #f
(list? 1492) ; => #f
(list? '()) ; => #t
(list? '(1 2 3)) ; => #t

リストは S 式を括弧でくくったもの。

アトムは S 式。 リストもそれ自体が S 式となる。

car とは

(car '(A B C)) ; => A
(car '(A)) ; => A
(car 'hotdog) ; => 未定義
(car '()) ; => 未定義

car は空でないリストの先頭の S 式を取り出す。 アトムと空のリストに対する操作は定義されていない。

cdr とは

(cdr '(A B C)) ; => (B C)
(cdr '(A)) ; => ()
(cdr 'hotdog) ; => 未定義
(cdr '()) ; => 未定義

cdr は空でないリストの先頭以外のリストを取り出す。 アトムと空のリストに対する操作は定義されていない。 cdr は常にリストとなる。

cons とは

(cons 'a '(b c)) ; => (a b c)
(cons 'a '()) ; => (a)
(cons 'a 'b) ; => 本では扱わない

cons は任意の S 式をリストの先頭につける。 第一引数は S 式。第二引数は任意のリスト。 ドット対は扱わないようだ。

null? とは何か

(null? '()) ; => #t
(null? '(a)) ; => #f
(null? 'a) ; => 本では扱わない

null? は空リストかどうかを調べる。 アトムに対する null? は定義されていない。

eq? とは何か

(eq? 'atom 'atom) ; => #t
(eq? '(1) '(1)) ; => 本では扱わない
(eq? 7 6) ; => 本では扱わない

eq? は同じアトムであるかどうかを調べる。 eq? はどちらも数でないアトムでなければならない。

1章はこれで終わり。

第2章:一度、もう一度、さらにもう一度、またもう一度、……

lat?

(define (lat? lis)
  (cond [(null? lis) #t]
        [(atom? (car lis)) (lat? (cdr lis))]
        [else #f]))

(lat? '()) ; => #t
(lat? '(a b c)) ; => #t
(lat? '((a) b c)) ; => #f
(lat? '(() b c)) ; => #f

lat? はリスト内の S 式がすべてアトムだった場合に #t を返す関数。

or

(or (null? '()) (null? '())) ; => #t
(or (null? '()) (null? '(a b c))) ; => #t
(or (null? '(a b c)) (null? '())) ; => #t
(or (null? '(a b c)) (null? '(a b c))) ; => #t

or の確認。

member?

(define member?
  (lambda (lis a)
    (cond [(null? lis) #f]
          [(eq? (car lis) a) #t]
          [else (member? (cdr lis) a)])))

(member? '(a b) 'a) ; => #t
(member? '(a b) 'c) ; => #f
(member? '() 'a) ; => #f

与えられたアトムがリスト内にあるかどうかを調べる関数。

再帰の練習って感じ。まずはじめに null? を質問するのがコツ。 ここらへんはまだまだ簡単。

そういえば、紙の本買ったのひさしぶりだなぁ。

(c) The King's Museum