Scheme 当你有结构和列表时,你如何对列表中的数字求和

Scheme 当你有结构和列表时,你如何对列表中的数字求和,scheme,racket,Scheme,Racket,所以我想把所有的数字加起来!这是我的密码 ;; An ATOM is one of: ;; -- Symbol ;; -- String ;; -- Number ;; An SEXP (S-expression) is one of: ;; -- empty ;; -- (cons ATOM SEXP) ;; -- (cons SEXP SEXP) 然而,一个错误显示为cond:所有问题结果都是错误的。我想知道那里发生了什么。您将结构访问器过程与列表操作过程混合在一起,这是行不通的

所以我想把所有的数字加起来!这是我的密码

;; An ATOM is one of: 
;; -- Symbol
;; -- String 
;; -- Number

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

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

您将结构访问器过程与列表操作过程混合在一起,这是行不通的-您必须保持一致,如果使用结构,则必须使用结构自己的过程

另外,您的
ATOM
结构看起来是错误的,因为它的意思是:一个ATOM由一个符号、一个字符串和一个数字组成(这三个东西,而不仅仅是其中一个!)。当然,
symbol?
number?
string?
谓词对该结构不起作用,这就是为什么
cond
抱怨所有条件都为false的原因

我建议你试试别的,原子是真正的原子,而不是结构。否则,您将不得不重新思考原子的结构,它的当前形式将无法按照您想象的方式工作。例如,这将起作用:

;; 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]))
让我们测试它,并注意原子是如何普通的模式原子,而不是
ATOM
struct的实例:

(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]))

请看下面的图片。当您编写
(定义struct ATOM(symbol string number))
时,您的意思是
ATOM
是三个元素的组合:一个符号、一个字符串和一个数字,而不仅仅是其中的一个@ÓscarLópez OP似乎想要的东西类似于C的工会。我不知道是否有任何计划的实施支持工会;这似乎对记忆不安全。当然,静态类型语言有代数数据类型之类的概念,但同样,这不适用于Scheme。谢谢!我想知道原子是否应该是一种结构。在这种情况下,原子是平的。所以我在想,在这种情况下,我们需要写原子?确定它是否是原子和SEXP的函数?是否是一个SEXP。同样,SEXP应该是一个列表,而不是一个结构。
(sum-numbers 
 (make-SEXP 'x 
            (make-SEXP 7
                       (make-SEXP "a" 
                                  '()))))
=> 7
 ;; 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]))