2016-07-10 6 views
0

다음과 같이 정의 된 구조와 유형을 곱하면 두 개의 숫자 함수가 작성되어야합니다. 그렇게하는 데 어려움이 있습니다. 모든 조언을 크게 주시면 감사하겠습니다.Typed/Racket : 주어진 자연수 정의 유형은 두 개의 숫자 함수를 곱해야합니다.

(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-nadd-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 기능을 썼다 기본 사례는 해당 분기에서 여전히 0이 될 것이기 때문입니다. 문제는'sub-nat'을 사용하는 것에 더 가깝습니다. 왜냐하면 그 버전이 ('Succ-n a '를 사용하는) 버전과'(Succ- nat a one)'). –

+0

@AlexKnauth OP의 사례를 다시 읽었을 때, 나는 그들의 기본 사례가 효과가 있었음을 알았습니다. 네, 서브 - 네이트의 구현은 파기되어 타입 체크를하지 않을 것이고,'add-nat'은 이미'Succ-n'을 사용하고 있기 때문에'multiply-nat'도 그것을 사용해야합니다. –

+0

'sub-nat'이 틀리다고 지정하고 기본 사례 만 남겨 두도록 수정해야합니까? –

관련 문제