2016-07-10 11 views
0

次の定義された構造体と型には、2つの数値の乗算が必要です。それをするのに困っている。アドバイスをいただければ幸いです。型付き/ラケット:指定された自然数定義型は、2つの数値を乗算する必要があります。

(define-struct Zero()) 

(define-struct Succ 
    ([n : Nat])) 

(define-type Nat (U Zero Succ)) 

(: one Nat) 
(define one (Succ (Zero))) 
(: two Nat) 
(define two (Succ one)) 

(: sub-nat : Nat Nat -> Nat) 
    (define (sub-nat a y) 
    (cond 
     [(Zero? a) a] 
     [(eq? one y) 
      (- a y)])) 

(: add-nat (-> Nat Nat Nat)) 
(define (add-nat a b) 
    (cond 
    [(Zero? a) b] 
    ((Zero? b) a) 
    [else (add-nat (Succ-n a) (Succ b))])) 

(: multiply-nat : Number Nat -> Nat) 
(define (multiply-nat a b) 
(cond 
    [(Zero? a) a] 
    [(Zero? b) b] 
    [else 
    (add-nat b (multiply-nat (sub-nat a one) b))])) 

答えて

1

お客様のsub-natの実装は間違っており、タイプチェックは行われません。それを修正することはできますが、意味的にはSucc-nmultiply-natadd-natの場合と同じように)とするのがより適切です。Succ-nsub1の教会番号に相当します。ここmultiply-natの修正(およびテスト)のバージョンがあります:問題がでない

(: nat->number : Nat -> Nonnegative-Integer) 
(define (nat->number n) 
    (if (Zero? n) 
     0 
     (add1 (nat->number (Succ-n n))))) 
+1

:テスト目的のために

(define (multiply-nat a b) (cond [(Zero? a) a] [(Zero? b) b] [else (add-nat b (multiply-nat (Succ-n a) b))])) 

、私はまた、実際の数字に教会の数字を変換するためのnat->number機能を書きましたそれらのブランチでは依然としてゼロになるからです。問題はあなたのバージョン( '(Succ-n a)'を使って)とオリジナル( ''サブナート ''を使って)の間で実際に異なる唯一のものであるため、 nat a one) ')。 –

+0

@AlexKnauth OPのケースを再度読んで、彼らのベースケースもうまくいくと思う。はい、サブルーチンの実装は破棄され、タイプチェックは行われません。また、 'add-nat'はすでに' Succ-n'を使用しているので、 'multiply-nat'もそれを使うべきです。 –

+0

これを編集して 'sub-nat'が間違っていると指定し、ベースケースだけを残しておきますか? –

関連する問題