compose函数首先应用最后一个函数,即它以相反的顺序应用发送的函数。例如:
((compose sqrt add1) 8)
上面将添加1到8,然后找到9的sqrt。
我想创建一个mycompose函数,它首先应用第一个发送的函数,然后应用第二个,第三个等等。因此,在上面的示例中,首先需要应用sqrt,然后再应用add1。我可以管理以下内容:
(define (mycompose L arg)
(let loop ((L L)
(res arg))
(cond
[(empty? L) res]
[else (loop (rest L) ((car L) res))])))
(mycompose (list sqrt add1) 8)
我相信有更好的方法。特别是,上面可以使用宏来实现,还允许多个参数轮流发送到每个函数?
答案 0 :(得分:3)
您描述的这种“逆向组合”通常称为画眉,the point-free package provides a thrush
function可以完全按照您的要求进行操作。但是,假设你想自己实现它。好吧,最简单的方法是重用compose
的现有实现,因为thrush
只是compose
且反转的参数:
(define (thrush . fs)
(apply compose (reverse fs))
事实上,这是无点程序包实现thrush
的方式。不过,这可能让您感到不满意,因为您不知道compose
是如何实现的。好吧,幸运的是,我们可以通过简单的折叠从头开始实现thrush
:
(define (thrush . fs)
(for/fold ([f values])
([g (in-list fs)])
(λ args (call-with-values (thunk (apply f args)) g))))
这里真正的技巧是使用call-with-values
,它可以正确处理返回多个值的函数。就像Racket的compose
一样,这将接受多个值并将它们作为多个参数传递给管道中的函数,从而在函数输入和函数输出之间创建良好的对称性。