手动合成两个函数

huangapple go评论52阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年3月9日 22:04:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/75685670.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定