サーチ…
defineを使う
#lang racket
(define (sum-of-list l)
(if (null? l)
0
(+ (car l)
(sum-of-list (cdr l)))))
(sum-of-list '(1 2 3 4 5)) ;; => 15
let-recを使う
#lang racket
(letrec ([sum-of-list (λ (l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))])
(sum-of-list '(1 2 3 4 5)))
;; => 15
letrec
を使って相互に再帰的な関数を書くことができletrec
:
#lang racket
(letrec ([even? (λ (n) (if (= n 0) #t (odd? (sub1 n))))]
[odd? (λ (n) (if (= n 0) #f (even? (sub1 n))))])
(list (even? 3)
(odd? 5)))
;; => '(#f #t)
名前付きletの使用
通常のlet
フォームは、ボディを実行する前に、各値を対応する識別子にバインドします。 "名前付きlet
"を使用すると、ボディを再帰的に再実行し、各識別子に新しい値を渡すことができます。
#lang racket
(let sum-of-list ([l '(1 2 3)])
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))
;; => 15
letの名前としてrec
を使用するのが一般的です。次のようになります。
#lang racket
(let rec ([l '(1 2 3 4 5)])
(if (null? l)
0
(+ (car l) (rec (cdr l)))))
;; => 15
recを使う
#lang racket
(require mzlib/etc)
((rec sum-of-list
(λ (l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l))))))
'(1 2 3 4 5))
;; => 15
;; Outside of the rec form, sum-of-list gives an error:
;; sum-of-list: undefined;
;; cannot reference an identifier before its definition
これはdefine
と似ていdefine
が、 sum-of-list
識別子はrec
フォームの外部には見えません。
明示的なλ
を使用しないようにするには、 sum-of-list
を(sum-of-list args ...)
に置き換えることができ(sum-of-list args ...)
。
#lang racket
(require mzlib/etc)
((rec (sum-of-list l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))
'(1 2 3 4 5))
;; => 15
再帰の代わりに高次関数を使う
正しい再帰パターンを表す高次関数があれば、再帰の代わりに高次関数を使用するのが一般的です 。私たちの場合は、 foldl
を使ってsum-of-numbers
を定義することができます:
#lang racket
(define (sum-of-numbers l)
(foldl + 0 l))
(sum-of-numbers '(1 2 3 4 5)) ;; => 15
リストのfoldl
直接呼び出すことは可能です:
#lang racket
(foldl + 0 '(1 2 3 4 5)) ;; => 15
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow