英文:
manual compostion of two functions
问题
我试图制作自己的(组合)函数,但我无法完成。
它需要按照以下方式工作:
让我们称这个函数为“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)) ; 或者 f(g),或者其他很多括号的组合
)
但不幸的是,我无法想出将这两个函数组合的方法。
所以我猜它需要比括号的简单操纵更加抽象/复杂。
英文:
I try to make my own (compose) function, but I can't get through it.
It needs to work as follow:
let's call that function "manual" - manual needs to take two arguments, and it has to compose them in a way that later we can call our manual like this: ((manual func1 func2) 1)
(so the output of the manual needs to be a procedure)
so if the func2 multiplies input by 2, and func1 raise it to the third power, then output of ((manual func1 func2) 1)
should be 8
(( 2*1)^3
)
I tried to write function like this:
(define (manual func1 func2)
(func1 (func2)) ; or f(g), or many other combinations of parenthesis
)
but unfortunately I couldn't came with idea of composing those two.
So I guess it needs to be a bit more abstract/complex than just some manipulation with parenthesis.
答案1
得分: 1
当你调用(manual f g)
时,你希望获得一个可以用更多参数调用的函数:
((manual f g) 0 1 2 3)
让我们首先简化这个需求,只接受一个参数:
((manual f g) 0)
为了获得一个具有一个参数的函数,你编写一个lambda形式:
(lambda (v) ...)
所以你可能会写如下内容:
(define (manual f g)
(lambda (v) ...))
如果你认为你应该能够填写剩下的代码。
英文:
When you call (manual f g)
you want to obtain a function that you can call with more arguments:
((manual f g) 0 1 2 3)
Let's simplify first this requirement and only accept one argument:
((manual f g) 0)
In order to obtain a function of one parameter, you write a lambda form:
(lambda (v) ...)
So you are probably going to write the following:
(define (manual f g)
(lambda (v) ...))
If think you should be able to fill the remaining code.
答案2
得分: 1
I want a function, manual
, that accepts two functions, f
and g
-
我想要一个函数,`manual`,它接受两个函数,`f` 和 `g` -
It should return a function, call it composition
-
它应该返回一个函数,称之为 `composition` -
When composition
is applied to an argument, arg
, it should return a result of f
applied to arg
, where g
is applied to f
's result -
当 `composition` 被应用到一个参数 `arg` 时,它应该返回 `f` 应用于 `arg` 的结果,其中 `g` 应用于 `f` 的结果 -
Let's test it -
让我们来测试一下 -
It would be nice if composition
didn't require a name. lambda
allows us to define a nameless, anonymous procedure -
如果 `composition` 不需要名字会很好。`lambda` 允许我们定义一个无名的、匿名的过程 -
If I want to make the composition accept multiple arguments, I can use apply
to apply f
to all args
-
如果我想让这个组合接受多个参数,我可以使用 `apply` 将 `f` 应用到所有的 `args` 上 -
If I want manual
to accept any number of functions, I can rewrite the composition to apply all of them in sequence using a left fold -
如果我想让 `manual` 接受任意数量的函数,我可以重写这个组合,使用 [left fold](https://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Fprivate%2Flist..rkt%29._foldl%29%29) 来依次应用它们 -
Above special behaviour is given to the first function in the sequence. If I want to make manual
generic, I can ask the caller to handle the specialized behaviour -
以上特定行为是针对序列中的第一个函数的。如果我想让 `manual` 通用化,我可以要求调用者处理特定行为 -
@PeterWinton points out that a typical compose function will apply the functions in right-to-left order. The manual
procedure we wrote above applies them left-to-right. It's worth knowing the difference and what's considered common in practice. Writing manual
to reflect this behaviour remains an exercise for the reader.
@PeterWinton 指出,[典型的 compose 函数](https://docs.racket-lang.org/reference/procedures.html#%28def._%28%28lib._racket%2Fprivate%2Flist..rkt%29._compose%29%29) 会按 _从右到左_ 的顺序应用函数。我们上面编写的 `manual` 过程按 _从左到右_ 的顺序应用它们。了解这两者之间的区别以及实际中被认为常见的方式是值得的。编写 `manual` 来反映这种行为仍然是读者的练习。
英文:
I want a function, manual
, that accepts two functions, f
and g
-
(define (manual f g)
...)
It should return a function, call it composition
-
(define (manual f g)
(define (composition ...)
...)
composition)
When composition
is applied to an argument, arg
, it should return a result of f
applied to arg
, where g
is applied to f
's result -
(define (manual f g)
(define (composition arg)
(g (f arg)))
composition)
Let's test it -
((manual
(lambda (x) (+ x 1))
(lambda (x) (* x 2)))
3)
8 ; (3 + 1) * 2
It would be nice if composition
didn't require a name. lambda
allows us to define a nameless, anonymous procedure -
(define (manual f g)
(lambda (arg)
(g (f arg))))
If I want to make the composition accept multiple arguments, I can use apply
to apply f
to all args
-
(define (manual f g)
(lambda args
(g (apply f args))))
((manual * add1) 10 20)
201 ; (10 * 20) + 1
If I want manual
to accept any number of functions, I can rewrite the composition to apply all of them in sequence using a 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
Above special behaviour is given to the first function in the sequence. If I want to make manual
generic, I can ask the caller to handle the specialized behaviour -
(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 points out that a typical compose function will apply the functions in right-to-left order. The manual
procedure we wrote above applies them left-to-right. It's worth knowing the difference and what's considered common in practice. Writing manual
to reflect this behaviour remains an exercise for the reader.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论