我需要在Scheme中为简单的算术表达式定义一个计算器。例如,在键入(calculator '( 1 + 2))
时,方案解释程序将打印3
。计算器将接受任何长度的表达式,并且表达式与右侧相关联。例如,在(calculator '(1 + 1 - 2 + 3 ))
中,表达式被解释为(1 + (1 - (2 + 3)))
,因此值为-3
。我假设表达式只有+
和-
运算符,输入中没有括号。我到目前为止编写了这个程序:
#lang lazy
(define (calculator exp)
(cond
((null? exp) 0)
(= (length (exp)) 1 exp)
(eq? '+ (cdr (cdr exp)) (+ (car exp) (calculator (cdr (cdr exp)))))
(else (eq? '- (cdr (cdr exp)) (- (car exp) (calculator (cdr (cdr exp)))))))
但是当我尝试像(calculator '(1 + 1 + 1))
这样的东西时,我收到了这个错误:
#%module-begin: allowed only around a module body in: (#%module-begin (define
(calculator exp) (cond ((null? exp) 0) (= (length (exp)) 1 exp) (eq? (quote +)
(cdr (cdr exp)) (+ (car exp) (calculator (cdr (cdr exp))))) (else (eq? (quote -)
(cdr (cdr exp)) (- (car exp) (calculator (cdr (cdr exp)))))))) (calculator
(quote (1 + 1 + 1))))
我对Scheme非常新,所以非常感谢任何帮助
答案 0 :(得分:2)
代码中的语法不正确。正如您对问题的评论所指出的那样,您错误地放了一些问题。在Scheme中,通过一致地缩进来“跟踪parens”可以获得很大的好处。这是一个让你大部分都在那里的版本。
(define (calculator exp)
(cond ((null? exp) 0) ; zero terms
((null? (cdr exp)) (car exp)) ; one term only (assumed number)
(else ; assumed three or more terms
(let ((operand1 (car exp))
(operator (cadr exp))
(operands (cddr exp)))
((case operator ; convert operator, a symbol, to its function
((+) +)
((-) -))
operand1
(calculator operands)))))) ; calculate the rest
> (calculator '(1 + 2))
3
> (calculator '(1 - 2 + 3))
-4
答案 1 :(得分:0)
为了转换
1 - 2 + 3
到
( - 1(+ 2 3))
你需要
所以你有3个案例:
1)list of end =>返回缓存值
否则在
之间切换2)缓存一个值
3)将函数应用于缓存值和表达式的其余部分
示例代码:
(define (calculator exp)
(define funcs (hasheq '+ + '- -))
(let loop ((exp exp) (toggle #t) (val #f))
(if (empty? exp)
val ; 1) end of list => return cached value
(if toggle
(loop (cdr exp) #f (car exp)) ; 2) cache value
((hash-ref funcs (car exp)) val (loop (cdr exp) #t #f)))))) ; 3) apply the function to the cached value and the rest of the expression