计划中的汽车实施

时间:2019-01-01 10:07:50

标签: scheme racket

我正在尝试自己编写方案中的cons函数。我已经编写了这段代码:

(define (car. z)
    (z (lambda (p q) p))) 

我正在尝试运行:

(car. '(1 2 3))

我希望得到数字1,但是它不能正常工作。

2 个答案:

答案 0 :(得分:1)

实现语言数据结构时,需要提供符合合同规定的构造函数和访问器:

(car (cons 1 2))   ; ==> 1
(cdr (cons 1 2))   ; ==> 2
(pair? (cons 1 2)) ; ==> 2

这里是一个例子:

(define (cons a d)
  (vector a d))
(define (car p)
  (vector-ref p 0))
(define (cdr p)
  (vector-ref p 1))

现在,如果您实现一个实现,则将实现read来遵循这种成对方式,以便'(1 2 3)将创建正确的数据结构,上面的简单规则仍然相同。

通过观察car,我可以想象cons看起来像这样:

(define (cons a d)
  (lambda (p) (p a d)))

它与闭包一起使用。现在,Scheme的堆栈计算机实现将分析代码中是否存在通过其范围的自由变量,从而将它们创建为框。包含ad的闭包与向量没有太大区别。

我敦促您实现一个简约的Scheme解释器。首先在Scheme中,因为您可以使用宿主语言,然后可以使用不同于Lisp语言的语言。您甚至可以in an esoteric language进行操作,但这非常耗时。

答案 1 :(得分:1)

Sylwester的答案很好。这是nullnull?conscarcdr-

的另一种可能的实现
(define null 'null)

(define (null? xs)
  (eq? null xs))

(define (cons a b)
  (define (dispatch message)
    (match message
      ('car a)
      ('cdr b)
      (_ (error 'cons "unsupported message" message))
  dispatch)

(define (car xs)
  (if (null? xs)
      (error 'car "cannot call car on an empty pair")
      (xs 'car)))

(define (cdr xs)
  (if (null? xs)
      (error 'cdr "cannot call cdr on an empty pair")
      (xs 'cdr)))

它是这样的-

(define xs (cons 'a (cons 'b (cons 'c null))))

(printf "~a -> ~a -> ~a\n"
        (car xs)
        (car (cdr xs))
        (car (cdr (cdr xs))))
;; a -> b -> c

在这些情况下会引发错误-

(cdr null)
; car: cannot call car on an empty pair

(cdr null)
; cdr: cannot call cdr on an empty pair

((cons 'a 'b) 'foo)
;; cons: unsupported dispatch: foo

define/match如果您喜欢甜的东西,可以加一点糖-

(define (cons a b)
  (define/match (dispatch msg)
    (('car) a)
    (('cdr) b)
    (('pair?) #t)
    ((_) (error 'cons "unsupported dispatch: ~a" msg)))
  dispatch)

((cons 1 2) 'car)   ;; 1
((cons 1 2) 'cdr)   ;; 2
((cons 1 2) 'pair?) ;; #t
((cons 1 2) 'foo)   ;; cons: unsupported dispatch: foo
相关问题