鉴于以下定义的结构和类型需要编写乘法两个数字函数。无法做到这一点。任何建议将不胜感激。
(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))]))
答案 0 :(得分:1)
您的sub-nat
实施不正确,不会进行类型检查。虽然您可以解决这个问题,但从语义上讲,在Succ-n
中使用multiply-nat
更为正确(正如您对add-nat
所做的那样),因为Succ-n
是教会数字相当于sub1
。这是multiply-nat
的更正(和测试)版本:
(define (multiply-nat a b)
(cond
[(Zero? a) a]
[(Zero? b) b]
[else
(add-nat b (multiply-nat (Succ-n a) b))]))
出于测试目的,我还写了一个nat->number
函数,用于将教会数字转换为实际数字:
(: nat->number : Nat -> Nonnegative-Integer)
(define (nat->number n)
(if (Zero? n)
0
(add1 (nat->number (Succ-n n)))))