我试图在Scheme中找到多个参数“compose”的“最佳”实现(我知道这是在某些实现中的内建,但假设我现在是使用一个没有这个的)。Scheme:使用fold实现n参数
对于2参数构建功能我有这样的:
(define compose
(lambda (f g)
(lambda x
(f (apply g x)))))
这样做的好处是,如果最右侧的功能需要额外的参数,这些仍然可以通过组合功能通过。这具有令人满意的特性,即在某物上组合身份功能不会改变该功能。
例如:
(define identity
(lambda (x) x))
(define list1
(compose identity list))
(define list2
(compose identity list1))
(list2 1 2 3)
> (1 2 3)
现在做一个“正论证”撰写我可以这样做:
(define compose-n
(lambda args
(foldr compose identity args)))
((compose-n car cdr cdr) '(1 2 3))
> 3
但这不再保留那该多好“身份”属性:
((compose-n identity list) 1 2 3)
> procedure identity: expects 1 argument, given 3: 1 2 3
问题是用于foldr命令的“初始”函数。它已内置:
(compose identity (compose list identity))
所以......我不确定最好的解决方法。 “与foldl”似乎是天然的更好的选择,因为我想将它与“身份”开始对左不是权 ...
但天真的实现:
(define compose-n
(lambda args
(foldl compose identity args)))
其中工程(必须扭转的功能应用程序的顺序):
((compose-n cdr cdr car) '(1 2 3))
> 3
因为现在我最终把身份功能左侧没有解决不了的问题!这就像,我需要使用“foldr”,但需要一些不同的“初始”值比身份函数...或更好的身份函数?显然我很困惑!
我想实现它无需编写明确的尾递归“循环” ...这似乎应该有一个优雅的方式来做到这一点,我只是卡住了。
[德克的答案](http://stackoverflow.com/questions/1693181/scheme-implementing-n-argument-compose-using-fold/1693202#1693202)(因为删除)有正确的想法:只需使用'values'而不是'identity'。这实际上是我的'compose'实现的方法:'(compose)'简单地返回'values'。 – 2009-11-09 00:02:50
谢谢!我现在唯一的问题是,我正在使用doens't支持call-with-values的方案解释器......有没有一种方法可以在现有计划的基础上实施“价值观”和“呼叫价值”? – 2009-11-09 13:08:30
我开发了一种方法来排序虚假的'价值'和'调用价值':新帖子出现了。 :-) – 2009-11-10 23:39:09