0

Basicly,what I want to do is this:

I have a function square(x) (define (square x) (* x x))(f(x)=x*x),and another function mul_two (define (mul_two x) (* 2 x))(g(x)=2*x), I want to construct a new function based on the above two functions, what the new function does is this: 2*(x*x)(p(x)=g(f(x))), how can I write this new function in scheme? Although its a pretty straight thing in mathmatical form I'm totally stuck on this .

3 Answers 3

3

The usual way to do what you're asking is by using compose, which according to the linked documentation:

Returns a procedure that composes the given functions, applying the last proc first and the first proc last.

Notice that compose is quite powerful, it allows us to pass an arbitrary number of functions that consume and produce any number of values. But your example is simple to implement:

(define (square x)   ; f(x)
  (* x x))

(define (mul_two x)  ; g(x)
  (* 2 x))

(define p ; g(f(x))
  (compose mul_two square))

(p 3) ; same as (mul_two (square 3))
=> 18

If for some reason your Scheme interpreter doesn't come with a built-in compose, it's easy to code one - and if I understood correctly the comments to the other answer, you want to use currying. Let's write one for the simple case where only a single value is produced/consumed by each function, and only two functions are composed:

(define my-compose ; curried and simplified version of `compose`
  (lambda (g)
    (lambda (f)
      (lambda (x)
        (g (f x))))))

(define p ; g(f(x))
  ((my-compose mul_two) square))

(p 3) ; same as (mul_two (square 3))
=> 18
Sign up to request clarification or add additional context in comments.

Comments

3
(define (new_fun x) (mul_two (square x)))

EDIT:

(define (square x) (* x x))
(define (mul_two x) (* 2 x))

(define (new_fun fun1 fun2) (lambda (x) (fun2 (fun1 x))))

((new_fun square mul_two) 10)

And you will get 200. (10 * 10 * 2)

Also, you can implement a general purpose my-compose function just as the compose in racket:

(define (my-compose . funcs)
  (let compose2
    ((func-list (cdr funcs))
     (func (lambda args (apply (car funcs) args))))
    (if (null? func-list)
      func
      (compose2
        (cdr func-list)
        (lambda args (func (apply (car func-list) args)))))))

And you can obtain new-fun by:

(define new-fun (my-compose mul_two square))

2 Comments

Thank you for the quick answer~~ actually, the situation is this: I got two functions, one function is passed a parameter to the other function, then this newly generated function is passed to another function.. do you know how to do this in scheme?
@linuxfish, I changed my answer and in the new answer, new_fun is just a function combining fun1 and fun2. (new_fun square mul_two) is the new function you want.
0

In #!racket (the language) you have compose such that:

(define double-square (compose double square))

Which is the same as doing this:

(define (double-square . args)
   (double (apply square args))) 

If you want to use Scheme (the standard) you can roll your own:

#!r6rs
(import (rnrs))

(define (compose . funs)
  (let* ((funs-rev (reverse funs))
         (first-fun (car funs-rev))
         (chain (cdr funs-rev)))
    (lambda args
      (fold-left (lambda (arg fun) 
                   (fun arg))
                 (apply first-fun args)
                 chain))))

(define add-square (compose (lambda (x) (* x x)) +))
(add-square 2 3 4) ; ==> 81

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.