我正在研究一个接受结构列表的函数,然后使用该结构列表生成一个函数,将符号列表处理成一个数字。每个结构都由一个符号组成,它将在消耗的第二个列表中,以及一个数字。生成的函数必须通过为每个符号分配基于先前结构的值来将符号列表转换为数字。使用抽象列表函数btw。
Example: ((function (list (make-value 'value1 10) (make-value 'value2 20)))
(list 'value1 'value2 'nothing 'value1)) would produced 40.
继承我的代码,但它仅适用于特定情况。
(define (function lst)
(lambda (x) (foldr + 0 (map (lambda (x)
(cond
[(equal? x (value-name(first lst)))(value-value (first lst))]
[else (value-value (second lst))]))
(filter (lambda (x) (member? x (map value-name lst)))x)))))
答案 0 :(得分:0)
看起来像是一个功课。您的解决方案的基本形状是可以的。我认为你在这里遇到问题的原因是代码中没有分解因此很容易在括号中丢失。
让我们从fold
开始,将+
作为最后一步计算的整数列表。
对于这个子任务,你有:
1)(名称,值)对的列表 2)名单
您需要获取值列表。写一个单独的函数,完成它并使用它。喜欢这个
(define (function lst)
(lambda (x) (foldr +
0
(to-values x lst)))
(define (to-values names names-to-values)
(map (lambda (name)
(to-value name names-to-values))))
(define (to-value n ns-to-vs)
...)
我们map
在names
上有另一个小功能。它将在n
中查找ns-to-vs
值并返回,如果没有,则返回0。
答案 1 :(得分:0)
使用foldr
解决问题有两种方法,研究和理解这两种方法都很有趣。在问题中尝试的第一个是首先生成一个包含所有值的列表,让foldr
负责添加它们。它可以用这样的简单方式实现:
(define (function lst)
(lambda (x)
(foldr +
0
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x))))
或者:使用foldr
可能过度,使用+
更简单:
(define (function lst)
(lambda (x)
(apply +
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x))))
在第二种方法中,我们“按原样”获取输入列表,让foldr
的{{1}}执行加法逻辑。这比使用lambda
的第一种方法更有效,因为不需要创建中间列表 - 在第一个版本中由foldr
生成的列表:
map
在这两种方法中,我使用assoc
来查找列表中的元素;如果你不允许使用它或者它对(define (function lst)
(lambda (x)
(foldr (lambda (e a)
(cond ((assoc e lst) => (lambda (p) (+ a (value-value p))))
(else a)))
0
x)))
创建的值不起作用,它很容易实现为辅助函数:make-value
获取一个名称 - 值对列表并返回具有给定名称的第一对。 assoc
=>
语法将cond
返回的对传递给assoc
的参数并执行。
因为你正在使用Racket,所以有一些语法糖可用于从另一个函数返回一个函数,试试这个等效的代码,为了简单起见:
lambda
或者这个:
(define ((function lst) x)
(foldr +
0
(map (lambda (e)
(cond ((assoc e lst) => value-value)
(else 0)))
x)))
无论如何,结果如预期:
(define ((function lst) x)
(foldr (lambda (e a)
(cond ((assoc e lst) => (lambda (p) (+ a (value-value p))))
(else a)))
0
x))