Higher-order functions - function

given,
(define (reduce f id lis)
(if (null? lis) id
(f (car lis) (reduce f id (cdr lis)))))
The length of a list can be defined in terms of reduce (as opposed to
using a recursive definition from scratch) as
(define (mylength lis) (reduce (lambda (x n) (+ 1 n)) 0 lis)).
Define the list function mymap (similar to map) that takes a unary function uf and a list lis in terms of reduce, that is, by determining the corresponding f and id in
(mymap uf lis) = (reduce f id lis),
Recall that mymap returns a list resulting from calling the function on every element in the input list such as (mymap (lambda(x) (* 2 x)) '(1 2 3)) = (2 4 6).
A little Explanation to how this has been done would be helpful, rather than a blatant answer. Thank You.

we have
(mymap uf lis) = (reduce f id lis) =
= (if (null? lis) id
(f (car lis) (reduce f id (cdr lis))))
which must be equal to
= (if null? lis) '()
(cons (uf (car lis)) (mymap uf (cdr lis))))
matching the corresponding entities, we get
id == '()
and, since (mymap uf lis) = (reduce f id lis), it is also (mymap uf (cdr lis)) = (reduce f id (cdr lis)), so we have
(f x y) = (cons (uf x) y)
Thus, we define
(define (mymap uf xs) ; multiple `x`-es :)
(reduce (lambda (x r)
(cons .... r))
'()
xs ))
your reduce is a right fold: its combining function receives an element x of the argument list xs, and the recursive result of working on the rest of list, as r.
r has all the elements of the rest of xs, which were already mapped through uf. All that's left to do to combine the given element x with this recursive result r, is to cons the (uf x) onto r.
It should pose no problem now to complete the definition by writing the actual code in place of the dots .... there.

Related

Solving a functional programming problem using dr.racket

I am trying to implement a function called funPower, which takes a function f, an integer n and returns the function f^n. For example ((funPower sqrt 2) 16) should return 2, which is (sqrt (sqrt 16)).
This is what I have so far but it is not giving me correct output
(define (funPower f n)
(lambda(x) (if (<= n 1)
(f x)
(f (funPower f (- n 1)) x))))
First, you're missing one more pair of parens.
(define (funPower1 f n)
(lambda (x) (if (<= n 1)
(f x)
;; (f ( funPower1 f (- n 1)) x))))
(f ( ( funPower1 f (- n 1)) x)))) )
;; ^^^ ^^^
because (funPower1 f (- n 1)) returns a function to be called on x, the future argument value, as you show with the example, ((funPower sqrt 2) 16).
Second, it's <= 0, not <= 1, and the function f shouldn't be called at all in such a case:
(define (funPower2 f n)
(lambda (x) (if (<= n 0)
;; (f x) ^^^
x
(f ( ( funPower2 f (- n 1)) x)))) )
Now that it's working, we see that it defers the decisions to the final call time, of ((funPower f n) x). But it really could do all the decisions upfront -- the n is already known.
To achieve that, we need to swap the (lambda and the (funPower, to push the lambda "in". When we do, it'll become an additional argument to such augmented funPower:
(define (funPower3 f n)
(if (<= n 0) (lambda (x)
x )
(funPower3 f (- n 1) (lambda (x) (f x)))) )
Now this is completely out of sync. Where's that third argument?
(define (funPower4 f n fun)
(if (<= n 0) fun
(funPower4 f (- n 1) (lambda (x) (fun (f x)))) ))
That's a little bit better, but what's the fun, originally? Where does it come from? It must always be (lambda (x) x) at first or else it won't be right. The solution is to make it an internal definition and use that, supplying it the correct argument the first time we call it:
(define (funPower5 f n)
(define (loop n fun)
(if (<= n 0) fun
(loop (- n 1)
(lambda (x) (fun (f x))))))
(loop n (lambda (x) x)))
This kind of thing would normally be coded as a named let,
(define (funPower5 f n)
(let loop ((n n)
(fun (lambda (x) x)))
(if (<= n 0) fun
(loop (- n 1)
(lambda (x) (fun (f x)))))))
We could also try creating simpler functions in the simpler cases. For instance, we could return f itself if n is 1:
(define (funPower6 f n)
(cond
((zero? n) .....)
((= n 1) .....)
((< n 0) .....)
(else
(let loop ((n n)
(fun .....))
(if (= n .....) fun
(loop (- n 1)
(lambda (x) (fun (f x)))))))))
Complete it by filling in the blanks.
More substantive further improvement is to use exponentiation by repeated squaring -- both in constructing the resulting function, and to have it used by the function we construct!
try this:
(define funpow
(lambda (f n)
((lambda (s) (s s n (lambda (x) x)))
(lambda (s n o)
(if (zero? n)
o
(s s (- n 1)
(lambda (x)
(o (f x)))))))))
(define sqrt_2 (funpow sqrt 2))
(define pow2_2 (funpow (lambda (x) (* x x)) 2))
(sqrt_2 16)
(pow2_2 2)

Remove multiple characters from a list if they are next to each other in Scheme

I have to make a Dr. Racket program that removes letters from a list if they are following the same letter as itself. For example: (z z f a b b d d) would become
(z f a b d). I have written code for this but all it does is remove the first letter from the list.
Can anyone help?
#lang racket
(define (remove-duplicates x)
(cond ((null? x)
'())
((member (car x) (cons(car(cdr x)) '())))
(remove-duplicates (cdr x))
(else
(cons (car x) (remove-duplicates (cdr x))))))
(define x '( b c c d d a a))
(remove-duplicates x)
(define (remove-dups x)
(cond
[(empty? x) '()]
[(empty? (cdr x)) (list (car x))]
[(eq? (car x) (cadr x)) (remove-dups (cdr x))]
[else (cons (car x) (remove-dups (cdr x)))]))
(cadr x) is short for (car (cdr x)) in case you didn't know.
Also, pattern matching makes list deconstruction often much more readable. In this case not so much, but it's still better than the other version:
(define (rmv-dups x)
(match x
[(list) (list)]
[(list a) (list a)]
[(cons a (cons a b)) (rmv-dups (cdr x))]
[__ (cons (car x) (rmv-dups (cdr x)))]))
This problem will be simpler if you introduce a helper function.
I recommend something like this (where angle brackets mean you need to fill out the details):
(define (remove-duplicates x)
(cond
[ <x is empty> '()] ; no duplicates in empty list
[ <x has one element> x] ; no duplicates in a list with one element
[ <first and second element in x is equal> (cons (car x) (remove-from-front (car x) (cdr x)))]
[else (cons (car x) (remove-duplicates (cdr x)))]))
(define (remove-from-front e x)
(cond
[ <x is empty> '()] ; e is not the first element of x
[ <e equals first element of x> (remove-from-front e (cdr x))] ; skip duplicate
[else (remove-duplicates x)])) ; no more es to remove

What this functions in Scheme language do?

I'm a newbie and I didn't understand very well the language. Could anyone please explain to me what this functions do?
First function:
(define (x l)
(cond
((null? l) 0)
((list? (car l))
(+ (x (car l)) (x (cdr l))))
(else (+ 1 (x (cdr l))))
))
Second function:
(define (x l)
(cond
((null? l) 0)
((list? (car l))
(+ (x (car l)) (x (cdr l))))
(else (+ (car l) (x (cdr l)))
))
I do understand the begining but the conditions I didn't understand. Any help?
I will call your second function y.
Writing in pseudocode,
x [] -> 0
x [a . b] -> x a + x b , if list a
x [a . b] -> 1 + x b , else, i.e. if not (list a)
y [] -> 0
y [a . b] -> y a + y b , if list a
y [a . b] -> a + y b , else, i.e. if not (list a)
So for example,
x [2,3] = x [2 . [3]]
= 1 + x [3]
= 1 + x [3 . []]
= 1 + (1 + x [])
= 1 + (1 + 0 )
and
y [2,3] = y [2 . [3]]
= 2 + y [3]
= 2 + y [3 . []]
= 2 + ( 3 + y [])
= 2 + ( 3 + 0 )
See? The first counts something in the argument list, the second sums them up.
Of course both functions could be called with some non-list, but then both would just cause an error trying to get (car l) in the second clause, (list? (car l)).
You might have noticed that the two are almost identical. They both accumulates (fold) over a tree. Both of them will evaluate to 0 on the empty tree and both of them will sum the result of the same procedure on the car and cdr when the car is a list?. The two differ when the car is not a list and in the first it adds 1 for each element in the other it uses the element itself in the addition. It's possible to write the same a little more compact like this:
(define (sum l)
(cond
((null? l) 0) ; null-value
((not (pair? l)) l) ; term
(else (+ (sum (car l)) (sum (cdr l)))))) ; combine
Here is a generalisation:
(define (accumulate-tree tree term combiner null-value)
(let rec ((tree tree))
(cond ((null? tree) null-value)
((not (pair? tree)) (term tree))
(else (combiner (rec (car tree))
(rec (cdr tree)))))))
You can make both of your procedures in terms of accumulate-tree:
(define (count tree)
(accumulate-tree tree (lambda (x) 1) + 0))
(define (sum tree)
(accumulate-tree tree (lambda (x) x) + 0))
Of course you can make a lot more than this with accumulate-tree. It doesn't have to turn into an atomic value.
(define (double tree)
(accumulate-tree tree (lambda (x) (* 2 x)) cons '()))
(double '(1 2 ((3 4) 2 3) 4 5)) ; ==> (2 4 ((6 8) 4 6) 8 10)

scheme, search-last funcion whithout several expressions

I must create a function - (search-last x list), i made this:
(define (search-last o lst)
(let loop ((lst lst))
(if (eqv? (caar lst) o)
(cdar lst)
(if (pair? (cdr lst))
(loop (cdr lst))
o))))
but for ex.
(define l '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
should be 1 but
my output is 5 i know where i made mistake but i dont know how can i improve it.
I cant use expression with "!" and vector, for, while, set, sort, reverse, list-ref, list-tail, append, length.
A tail recursive solution using named let
(define (search-last o lst)
(let loop ((lst lst) (match #f)) ; when not found match is #f
(cond ((null? lst) match) ; return last match at the end
((eqv? (caar lst) o) ; when found
(loop (cdr lst) (cdar lst))) ; we recurse with new match
(else (loop (cdr lst) match))))); or we keep the old match
You could have created your own reverse function and reverse the list in your named let loop. But my understanding is that this is not the point of the exercise.
This will work:
(define (search-last o lst)
(or
(let loop ((lst lst))
(cond
((null? lst) #f)
((eqv? (caar lst) o) (or (loop (cdr lst)) (cdar lst)))
(else (loop (cdr lst)))))
o))
The trick is that if you find a pair with the required first element, the or clause will search the rest of the list. If it returns #f, i.e. if there is no other such pair in the remaining list, then the clause will return (cdar lst). Otherwise it will return the result of the recursive search-last call. The outer or does the same with the final result, i.e. replacing #f with the argument o.
Testing:
> (search-last 1 '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
2
> (search-last 2 '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
1
> (search-last 3 '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
5
> (search-last 4 '((1 . 2) (2 . 5) (3 . 5) (2 . 1)))
4
FWIW, here's a tail-recursive version:
(define (search-last o lst)
(let loop ((lst lst) (res o))
(cond
((null? lst) res)
((eqv? (caar lst) o) (loop (cdr lst) (cdar lst)))
(else (loop (cdr lst) res)))))

Using abstract list functions to iterate over a list of functions in Scheme

How can I write a function max-list-function that consumes a list of functions, then produces a function f such that for every x, (f x) produces the maximum value of all the functions g in the list of functions?
For example (max-list-function (lambda (n) (+ n 4)) (lambda (n) (- 15 n))))
produces a function such that (f 2) returns 13 and (f 10) returns 14.
This is to be done with abstract list functions (filter, foldr, map, ...) without recursion.
Try this:
(define (max-list-function flist)
(lambda (n)
(foldr max -inf.0
(map (lambda (f) (f n))
flist))))
Use it like this:
(define f (max-list-function
(list (lambda (n) (+ n 4)) (lambda (n) (- 15 n)))))
(f 2)
> 13.0
(f 10)
> 14.0