【问题标题】:Scheme - Writing a bind function for association lists?方案 - 为关联列表编写绑定函数?
【发布时间】:2018-04-13 01:02:22
【问题描述】:

我正在尝试在 Scheme 中编写一个函数,它只是使用set! 创建一个关联列表。

该函数将接受三个参数:键、值和关联列表,并返回新的关联列表。我的代码如下:

(define al '((A 1) (B 2) (C 3)))

(define (bind k v al)
    (cond
       ((null? al) set! al '((k v)))
       (else (set-car! al '(k v)))))

我希望代码按如下方式工作:

现有关联列表((A 1) (B 2) (C 3))

函数调用: (bind D 4 al)

输出: ((A 1) (B 2) (C 3) (D 4))

但我收到错误:set!: bad syntax in: set! 首次使用 set!

我如何错误地使用set!

【问题讨论】:

    标签: functional-programming scheme racket


    【解决方案1】:

    您缺少 set! 调用周围的括号:

    (define (bind k v al)
        (cond 
            ((null? al) (set! al '((k v))))
            (else (set-car! al '(k v))))))
    

    顺便说一句,你还有其他问题:

    1. set! 设置的是局部变量,而不是全局变量。您的函数应该返回al 的新值。要使用它,你需要做(set! al (bind 'D 4 al))。还要注意调用时需要引用D,否则会尝试使用变量D的值。
    2. 变量不在带引号的列表中计算。因此,您将文字符号 kv 放入关联列表,而不是这些参数的值。
    3. set-car! 将替换列表的第一个元素,而不是向列表中添加新元素。您需要使用cons 添加到列表中。

    正确的代码应该是:

    (define (bind k v al)
        (cond 
            ((null? al) (set! al (list (list k v)))
            (else (set! al (cons (list k v) al))))
        al)
    

    但是加入一个空列表和创建一个新列表是一样的,所以不需要null?检查;这两种情况是一样的。只是:

    (define (bind k v al)
        (cons (list k v) al))
    

    【讨论】:

    • 您的绑定函数版本是否存在格式错误?在最后一行悬挂的“al”之后,您似乎缺少右括号。
    • 找到了,好像你在第一个条件句的末尾缺少了一个右括号
    • 总是 consal上设置新值?如果k 已经设置了怎么办?
    • @user633183 搜索 alist 会返回第一个匹配项,因此 consing 始终有效,并且比搜索要更新的匹配项更省时。它还允许通过简单地弹出绑定来恢复绑定。
    • @Barmar 聪明!我没有考虑过。谢谢回复?
    猜你喜欢
    • 1970-01-01
    • 2016-05-24
    • 2017-08-13
    • 2017-04-05
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    相关资源
    最近更新 更多