我想在方案中定义一个for-n函数,该函数有3个参数,start和stop是整数,fn是函数。我希望for-n函数用start然后start + 1来调用fn,最后用stop来调用 另外,我想在列表中存储fn返回的所有值。请帮我开始吧我是一名经验丰富的程序员,但刚刚开始学习计划。
这是我得到的功能定义:
[编辑]
(define (fn a)
a
)
(define (for-n start stop fn)
(cond
((> start stop) (quote ()))
((= start stop) (list(fn start)))
(else (list(for-n (+ start 1) stop fn)))
)
)
> (for-n 3 5 fn)
(list (list (list 5)))
当调用(for-n 3 5 fn)时,我希望它返回 (3 4 5),我做错了什么?
[编辑-2]
感谢大家的帮助。我现在正在运作。这是我得到的:
(define (for-n start stop fn)
(cond
((> start stop) (quote ()))
((= start stop) (list(fn start)))
(else (cons (fn start) (for-n (+ start 1) stop fn)))
)
)
答案 0 :(得分:5)
您很少想使用list
递归构建列表。列表使用cons
和null
(又名'()
)构建; list
只是一个便捷函数,用于创建固定大小的列表。
(list 1 2 3) = (cons 1 (cons 2 (cons 3 null)))
你的cond
条款中应该只有两个案例:要么已经完成,要么你没有。
示例帮助。特别是,选择与递归调用相关的示例。您添加了示例(for-n 3 5 fn)
。怎么样(for-n 4 5 fn)
;该怎么回事?现在,鉴于start
= 3
,stop
= 5
,(for-n 4 5 fn)
=您认为它应该产生的任何内容,您如何构建您认为的答案{ {1}}应该生成?
我强烈推荐How to Design Programs(在线提供文字)作为函数式编程的介绍。
答案 1 :(得分:2)
以下是使用SRFI 1的解决方案:
(define (for-n start stop fn)
(map fn (iota (- stop start) start)))
如果这是作业,那么您可以自定义iota
,也可以map
。 :-D
使用不同策略的另一种解决方案(也使用SRFI 1):
(define (for-n start stop fn)
(unfold-right (lambda (x) (< x start))
fn sub1 (sub1 stop)))
其中sub1
== (lambda (x) (- x 1))
。当然,在这种情况下,您必须自己实施unfold-right
。
希望从以上两个示例解决方案中,您有足够的想法来构建自己的从头开始的解决方案。 : - )
答案 2 :(得分:1)
我也是新手计划,但这是我想出的一个似乎对我有用的通用for循环:
(define (for i end-cond end-fn fn var)
(if (end-cond i)
var
(for (end-fn i) end-cond end-fn fn (fn var))
)
)
所以规范:
for (i=0; i > 5; i++) {
print i;
}
return i;
可以写成:
(define i 0) (for i (lambda (x) (> 5 x)) (lambda (y) (+ 1 y)) display i)
...你可以看到为什么范式不能很好地转换,尽管你可以用命名函数替换这些lambda来使它更具可读性。
-
自编2015:
这很糟糕,而且执行函数式编程是错误的。基于“地图”或“折叠”的方法要好得多。