[Lisp] 真偽値と条件判断 (プログラミングGauche p101 練習問題)

プログラミングGaucheをP101まで読み進めました。
notの書き方で手こずりましたが、練習問題を解きました。

any-predを作成してみる

手続きを返す処理なので、lambda式を返せば良さそうです。
いくつかの述語を引数にとって処理を行うので、可変長引数を使って実現してみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#! /usr/bin/env gosh
;; coding: utf8
 
;; any-checkを定義して再帰的に呼び出します。
;; 条件にマッチしたら#tを返して, 合わなければ再帰的に呼び出します。
(define (any-pred . preds)
  (define (any-check pred x)
    (cond ((null? pred) #f)
          (((car pred) x) #t)
          (else (any-check (cdr pred) x))))
  (lambda (x) (any-check preds x)))
 
(define positive-or-integer? (any-pred integer? positive?))
 
(define (main args)
  (print (positive-or-integer? 4))
  (print (positive-or-integer? 1.2))
  (print (positive-or-integer? -1.3))
  (print (positive-or-integer? -1))
  0)
 
gosh>#t
#t
#f
#t

every-predを作成してみる

every-predは全ての条件をクリアした時に真になるので, 条件にマッチしない場合は即座に#fを返します. 条件にマッチしたした時には再帰的に再帰的にサブ関数を呼び出します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#! /usr/bin/env gosh
;; coding: utf8
 
(define (every-pred . preds)
  (define (every-check pred x)
    (cond ((null? pred) #t)
          ((not ((car pred) x)) #f)
          (else (every-check (cdr pred) x))))
  (lambda (x) (every-check preds x)))
 
(define positive-integer? (every-pred integer? positive?))
 
(define (main args)
  (print (positive-integer? 4))
  (print (positive-integer? 1.2))
  (print (positive-integer? -1.3))
  (print (positive-integer? -1))
  0)
 
gosh>#t
#f
#f
#f

末尾再帰の書き方は上記であっているのか不安ですが、一旦目的は達成しています。

0 件のコメント :

コメントを投稿