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