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.
>Solution :
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 called with an argument, arg, it should return a result of arg applied to f, where f‘s result applied to g –
(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 pass all arguments to f –
(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