2016-05-26 3 views
0

この関数をfoldrに変換する方法は不思議です。特にベースケースは、エラーです。パラメータはリストであり、リストの要素です。関数は、パラメータ(x)の要素の要素数を数えます。基本ケースがエラーのときにfoldrを使用する

; [List-of X] X -> number or error 
; Count number of elements to X 
(define (cnt l x) 
    (cond 
    [(empty? l) (error x "not found")] 
    [(symbol=? (first l) x) 0] 
    [else (add1 (cnt (rest l) x))])) 
+0

通常のラケットでは、私はそれが不可能だと確信しています。しかし、DrRacketで '#lang lazy'を使用すると可能かもしれませんが、私はそれを試みます。 –

+0

普通のラケットでは可能ですが、奇妙な場所では余分な 'ラムダ'とゼロ引数の関数アプリケーションが必要です。 '#lang lazy'を使うと、これを普通の方法で書くことができます。 –

答えて

1

は、これは通常の厳格なラケットで明らかな方法では不可能ですが、あなたはDrRacketファイルの先頭に#lang lazyを置けばそれが可能である:それを使用して

#lang lazy 

; [List-of X] X -> number or error 
; Count number of elements to X 
(define (cnt l x) 
    (foldr (lambda (y cnt-rest) 
      (cond [(symbol=? y x) 0] 
       [else (add1 cnt-rest)])) 
     (error x "not found") 
     l)) 

> (cnt (list) 'a) 
a: not found 
> (cnt (list 'a) 'a) 
0 
> (cnt (list 'a 'b 'c) 'a) 
0 
> (cnt (list 'a 'b 'c) 'b) 
1 
> (cnt (list 'a 'b 'c) 'c) 
2 
> (cnt (list 'a 'b 'c) 'd) 
d: not found 
> (cnt (list 'a 'b 'c 'b 'a 'b 'c) 'c) 
2 

lambda式とゼロ引数関数のアプリケーションをラップすることで、通常のラケットでこれを行うこともできます。

#lang racket 

; [List-of X] X -> number or error 
; Count number of elements to X 
(define (cnt l x) 
    ((foldr (lambda (y cnt-rest) 
      (lambda() 
       (cond [(symbol=? y x) 0] 
        [else (add1 (cnt-rest))]))) 
      (lambda() 
      (error x "not found")) 
      l))) 

これは非常に扱いにくく、理解しにくいものですが、またracket/promiseからdelayforceを使用して別の方法でこれを表現することができます。

#lang racket 

; [List-of X] X -> number or error 
; Count number of elements to X 
(define (cnt l x) 
    (force (foldr (lambda (y cnt-rest) 
        (delay 
        (cond [(symbol=? y x) 0] 
          [else (add1 (force cnt-rest))]))) 
       (delay 
        (error x "not found")) 
       l))) 

delayフォームは余分lambda sがあった場所に行く、とforce呼び出しは、余分なゼロ引数の関数呼び出しがあった場所に行きます。 #lang lazy言語はあなたのためにそこにこれらのdelay sおよびforce Sを置き、そう

#lang lazy 

; [List-of X] X -> number or error 
; Count number of elements to X 
(define (cnt l x) 
    (foldr (lambda (y cnt-rest) 
      (cond [(symbol=? y x) 0] 
       [else (add1 cnt-rest)])) 
     (error x "not found") 
     l)) 

が前に働いた理由です。それはどこにでもdelaysとforcesを追加しました。そして、それぞれdelayフォームは余分なものを追加するのと同じです(他のものも含めて)forceコールは余分なゼロ引数の関数呼び出しを追加するようなものです。

+0

ありがとうございます。私は理解しやすく、foldrバージョンと同じくらい簡単であるので、私は元のバージョンにとどまると思います。 – user1897830

+0

はい。元のバージョンは間違いなく理解しやすいです。 –

関連する問題