[英]I'm trying to create a function with expression() inside, but I get an error
[英]I'm stuck trying to implement this function in Racket and ML
我有这个任务:
考虑一个列表,其中每个元素都是长度为 2 的嵌套列表。每个嵌套列表的第一个元素是 0 或 1。每个嵌套列表的第二个元素是一些 integer。下面是 Scheme 中的示例输入。
'((0 1) (1 2) (1 3) (0 4) (0 3))
出于这个问题的目的,我们将每个嵌套列表的第一个元素称为键,将嵌套列表的第二个元素称为值。 现在考虑一个 function,
count_by_cat
,它将这样的列表作为输入并产生一个二元素列表,其中
- 第一个元素是所有以 0 为键的嵌套列表的值之和,并且
- 第二个元素是所有以 1 为键的嵌套列表的值之和
在中实现
count_by_cat
- (a) 球拍,以及
- (b) 毫升。
创建辅助函数可能会有所帮助。 也不要忘记
map
和filter
(filter
不是 ML 的内置功能)。
我是 Racket 和 ML 的新手。 我坚持使用 Racket 中的访问列表和内容。 ML 的一些帮助也很好。
那么建议您使用高阶函数,例如map和filter 。
事实上,将我们的数据作为一个整体来操作是很容易的,而不是在精神上一次只关注一个元素。 有些人可能会争论哪种方法(即前一种方法)是函数式编程范例的本质。
在球拍中,
(define (count_by_cat ls)
“返回一个二元列表”
(list
;; .....
;; ..... ))
其中第一个元素是
(sum-of
所有嵌套列表的值
(map value
以 0 为键
(filter (lambda (x) (= 0 (key x))) ls)))
第二个元素是所有嵌套列表的值之和
(sum-of
(map value
以 1 为键
(filter (lambda (x) (= 1 (key x))) ls))) ))
所以我们需要定义访问嵌套列表的辅助函数,
(define (key n) (car n))
(define (value n) (cadr n))
以及 function 的sum-of
,用于汇总列表中的数值:
(require math/base)
(define (sum-of ls)
(sum ls))
这很容易编写,也很容易维护。
性能更高的代码将通过输入一次完成所有操作,如另一个答案所示。 它将所有逻辑融合到一个循环体中。 编写和维护起来可能更脆弱。
关于map
和filter
的提示有点转移注意力(而且关于它们不是 ML 语言的错误也是错误的); 帮助程序 function 非常有用,但它是您想要的折叠,它基本上使用列表的当前元素和累加器值调用 function,并使用它返回的值作为下一个元素的累加器,最终返回值整个折叠。
例如,在 ocaml 中,使用折叠对整数列表求和:
let sum = List.fold_left (+) 0 [ 1; 2; 3; 4; 5 ];;
( (+)
是中缀运算符+
的 function 版本)。
或者您在 Racket 中的问题,使用for/fold
comprehension ,并返回两个值而不是双元素列表,这在 Racket 和 Scheme 中更为惯用(在 ocaml 和大概标准 ML 中,您将返回一个双元素元组而不是列表,并获取元组列表)。
(define (count-by-cat lol)
(for/fold ([zero-sum 0]
[one-sum 0])
([elem (in-list lol)])
(case (first elem)
[(0) (values (+ zero-sum (second elem)) one-sum)]
[(1) (values zero-sum (+ one-sum (second elem)))])))
您也可以使用foldl
,但for/fold
通常更易于使用,尤其是在处理多个值或其他重要情况时。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.