如何使用初始值创建一个alist

时间:2018-01-01 23:08:08

标签: functional-programming scheme

我学习计划(使用guile),我发现需要创建一个初始列表,其中包含一些键和空列表作为其值。我想知道在做这样的事情时最好的做法是什么。我的目标是保持这种状态,以便稍后我可以将项目添加到列表中。这就是我现在所拥有的:

(define buckets
  `((hourly . ())
    (daily . ())
    (monthly . ())
    (yearly . ())))

但是,在尝试assoc-set!时,将项目附加到列表时,这不起作用。然而,这有效:

(define buckets
  (acons 'hourly '()
         (acons 'daily '()
                (acons 'monthly '()
                       (acons 'yearly '() '())))))

显然不是最好看的代码。是否有更惯用的方式来建立这样的列表?也许我完全错了。最终目标是拥有这些桶,我可以通过它们的密钥在后面的代码的不同部分引用它们。

谢谢!

2 个答案:

答案 0 :(得分:0)

scheme@(guile-user)> (acons 'hourly '()
         (acons 'daily '()
                (acons 'monthly '()
                       (acons 'yearly '() '()))))
$2 = ((hourly) (daily) (monthly) (yearly))

相同
scheme@(guile-user)> '((hourly) (daily) (monthly) (yearly))
$3 = ((hourly) (daily) (monthly) (yearly))

scheme@(guile-user)> (equal? $2 $3)
$4 = #t

编辑 assoc-set!在这种情况下不起作用,因为这些列表不可变。实现可变列表同时仍然缩短定义方式的一种方法是使用此表达式:

(map list '(hourly daily montly yearly))

答案 1 :(得分:0)

我的回答是在Scheme中,但很容易被翻译成guile

如果你想要一个高级解决方案,你可以采用一种方法,一旦完成,它将为你提供一个抽象层和更容易的数据管理。

迈出对象建模的一步!

根据行为(您支持的方法集),您希望自己的对象具有,通常应该如下所示:

(define make-state-manager
      (lambda()
             (let ((data_lst '()))
                   (letrec
                        ((get-lst (lambda (key) (assoc key data_lst)))
                        ((get-data (lambda (key) (assoc-ref key data_lst)))
                        ((add-item (lam ...)
                          ... here you should have add-data , remove-data etc.
                          (action_n ....)                       
                          (dispatch (lambda (action)
                                    (cond ((eq? action ’full-list) get-lst)
                                          ((eq? action ’value) get-data)
                                          ((eq? action ’add-to-list) add-item)
                                          ...
                                          ((eq? action ’action_n) func_n)
                                          (else (error "Unknown request: ~s" action)))))
                   )
                   dispatch))
                   ))

                   ...)))

用法:

>(define data_manager (make-state-manager))
> data_manager 
> #<procedure... >
> ((data_manager 'add-data) 'hourly '())
> ((data_manager 'value) 'hourly)
> ()
> ((data_manager 'full-list) 'hourly)
> (hourly . ())   

说明: 首先,让我们创建一个本地状态,以便您可以运行

(define data_manager1 (make-state-manager))
(define data_manager2 (make-state-manager))

他们将拥有不同的范围,这些行动不会相互影响。

然后在letrec中使用您的方法名称定义对象方法。

在发送(向用户发送:)中,您可以设置用户将使用的方法名称。

来源:我的大脑&amp;这个疯狂的book

如果这让你的思绪太过沉重 - 稍后再回来......