两个功能的手动组合

问题描述 投票:0回答:2

我尝试制作自己的(撰写)功能,但我无法通过它。

需要按以下方式工作:

让我们称该函数为“manual”——manual 需要接受两个参数,并且它必须以一种方式组合它们,以便以后我们可以这样调用我们的 manual:

((manual func1 func2) 1)
(因此 manual 的输出需要是一个过程)

所以如果 func2 将输入乘以 2,并且 func1 将其提高到三次方,那么

((manual func1 func2) 1)
的输出应该是
8
(
( 2*1)^3
)

我试过这样写函数:

(define (manual func1 func2) 
    (func1 (func2)) ; or f(g), or many other combinations of parenthesis
)

但不幸的是,我无法想到组成这两个。

所以我想它需要更抽象/复杂一点,而不仅仅是一些带有括号的操作。

racket
2个回答
1
投票

我想要一个函数,

manual
,它接受两个函数,
f
g
-

(define (manual f g)
  ...)

它应该返回一个函数,调用它

composition
-

(define (manual f g)
  (define (composition ...)
    ...)
  composition)

composition
应用于参数
arg
时,它应该返回
f
应用于
arg
的结果,其中
g
应用于
f
的结果-

(define (manual f g)
  (define (composition arg)
    (g (f arg)))
  composition)

让我们测试一下-

((manual
  (lambda (x) (+ x 1))
  (lambda (x) (* x 2)))
 3)
8 ; (3 + 1) * 2

如果

composition
不需要名字就好了。
lambda
允许我们定义一个无名的匿名过程 -

(define (manual f g)
  (lambda (arg)
    (g (f arg))))

如果我想让组合接受多个参数,我可以使用

apply
f
应用于所有
args
-

(define (manual f g)
  (lambda args
    (g (apply f args))))
((manual * add1) 10 20)
201 ; (10 * 20) + 1

如果我想要

manual
接受任意数量的功能,我可以使用 left fold -

重写组合以按顺序应用所有功能
(define (manual f . more)
  (lambda args
    (foldl (lambda (f x) (f x))
           (apply f args)
           more)))
((manual * add1 add1 add1 add1 add1) 10 20)
205 ; (((((10 * 20) + 1) + 1) + 1) + 1) + 1

上述特殊行为被赋予序列中的第一个函数。如果我想让

manual
通用,我可以要求调用者处理专门的行为 -

(define (manual . funcs)
  (lambda (init)
    (foldl (lambda (f x) (f x))
           init
           funcs)))
((manual
  (curry apply *) ; specific behaviour
  add1
  add1
  add1
  add1
  add1)
 (list 10 20)) ; multiple arguments collected in a list
205 ; (((((10 * 20) + 1) + 1) + 1) + 1) + 1

@PeterWinton 指出 typical compose function 将按 right-to-left 顺序应用函数。我们上面写的

manual
过程应用它们 left-to-right。了解其中的区别以及在实践中被认为是常见的是值得的。写
manual
来反映这种行为仍然是读者的练习。


1
投票

当您调用

(manual f g)
时,您想要获得一个可以调用更多参数的函数:

((manual f g) 0 1 2 3)

让我们先简化这个要求,只接受一个参数:

((manual f g) 0)

为了获得一个参数的函数,你写一个lambda形式:

(lambda (v) ...)

所以你可能会写以下内容:

(define (manual f g)
  (lambda (v) ...))

如果你认为你应该能够填写剩余的代码。

© www.soinside.com 2019 - 2024. All rights reserved.