2014-11-04 27 views
0
;; An ATOM is one of: 
;; -- Symbol 
;; -- String 
;; -- Number 

;; An SEXP (S-expression) is one of: 
;; -- empty 
;; -- (cons ATOM SEXP) 
;; -- (cons SEXP SEXP) 

所以我想总结所有的数字在SEXP!这里是我的代码,计划你如何总结列表中的数字当你有结构和列表清单

;; sum-numbers: sexp -> Number 

(define (sum-numbers sexp) 
(cond 
    [(empty? sexp) 0] 
    [(ATOM? (first sexp)) (+ (atom-sum-numbers (first sexp)) 
          (sum-numbers (rest sexp)))] 
    [(SEXP? (first sexp)) (+ (sum-numbers (first sexp)) 
          (sum-numbers (rest sexp)))])) 

;; atom-sum-numbers: Atom -> Number 
(define (atom-sum-numbers a) 
    (cond 
     [(symbol? a) 0] 
     [(number? a) (+ (ATOM-number a) 
        (atom-sum-numbers a))] 
     [(string? a) 0])) 

然而,一个错误说cond:所有问题的结果都是假的。我想知道那里发生了什么。

+0

看看[文档](http://docs.racket-lang.org/reference/define-struct.html)。当你写'(define-struct ATOM(symbol string number))'时,你说'ATOM'是三个元素的组合:一个符号,一个字符串和一个数字 - 不只是其中的一个! – 2014-11-05 01:18:42

+1

@ÓscarLópezOP似乎想要的东西类似于C的工会。我不知道是否有计划实施支持工会,这似乎记忆不安全。当然,静态类型语言具有代数数据类型的概念,但是这不适用于Scheme。 – 2014-11-05 04:15:55

回答

1

您正在将struct accessor过程与列表操作过程混合在一起,这不起作用 - 您必须保持一致,如果使用了结构,那么您必须使用结构自己的过程。

此外,您ATOM结构看起来错误的,因为它是,它在说:原子由一个符号,一个字符串一些了(三件事,不只是其中之一!)。当然,symbol?,number?string?谓词不适用于该结构,这就是为什么cond抱怨所有条件都是错误的原因。

我建议你试试别的,其中原子真的是原子,而不是结构。否则,你将不得不重新考虑ATOM结构,目前的形式不会按照你想象的方式工作。举例来说,这将工作:

(define (sum-numbers sexp) 
    (cond 
    [(empty? sexp) 0] 
    [(SEXP? (SEXP-ATOM sexp)) (+ (sum-numbers (SEXP-ATOM sexp)) 
           (sum-numbers (SEXP-SEXP sexp)))] 
    [else (+ (atom-sum-numbers (SEXP-ATOM sexp)) 
      (sum-numbers (SEXP-SEXP sexp)))])) 

(define (atom-sum-numbers a) 
    (cond 
    [(symbol? a) 0] 
    [(number? a) a] 
    [(string? a) 0])) 

测试一下,并注意原子如何是纯计划数,而不是ATOM结构的实例:

(sum-numbers 
(make-SEXP 'x 
      (make-SEXP 7 
         (make-SEXP "a" 
            '())))) 
=> 7 
+1

谢谢!我想知道ATOM是否应该是一个结构。在这种情况下,ATOM是平坦的。所以我想在这种情况下,我们需要写ATOM?函数确定它是否是ATOM和SEXP?无论是SEXP。 – ads27 2014-11-05 18:08:05

+0

另外,SEXP应该是一个不是结构的列表。 – ads27 2014-11-05 22:07:25

0
;; atom? : Any -> Boolean 
;; true if input is an Atom false otherwise 
(define (atom? at) 
    (or (number? at) 
     (symbol? at) 
     (string? at))) 

;; sexp? : Any -> Boolean 
;; true if input is n Sexp, false otherwise 
(define (sexp? s) 
    (or 
    (empty? s) 
    (and (cons? s) 
      (atom? (first s)) 
      (sexp? (rest s))) 
    (and (cons? s) 
      (sexp? (first s)) 
      (sexp? (rest s))))) 

;; sum-numbers: sexp -> Number 
;; given a sexp returns the sum of all the Numbers in the list 

;; sum-numbers: Sexp -> Number 
(define (sum-numbers sexp) 
    (cond 
    [(empty? sexp) 0] 
    [(atom? (first sexp)) (+ (atom-sum-numbers (first sexp)) 
           (sum-numbers (rest sexp)))] 
    [(sexp? (first sexp)) (+ (sum-numbers (first sexp)) 
           (sum-numbers (rest sexp)))])) 


;; atom-sum-numbers: anything(symbol number or string) -> Number 
;; if the given is a number, add it 

(define (atom-sum-numbers a) 
    (cond 
    [(symbol? a) 0] 
    [(number? a) a] 
    [(string? a) 0]))