;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname higher-order-functions-before) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f () #f))) ; Higher Order Functions (require "student-extras.rkt") ; Optionally, first go over java's `Optional` ; ; Optionally, first go over `while.rkt` ; ; Optionally: Threading macro ; (define/contract (make-list-getter k) (-> natural? (-> list? any?)) (λ(data) (list-ref data k))) ; stub (check-expect ((make-list-getter 3) '(a b c d e)) 'd) (define COURSES '((ibarland 380 11) (ibarland 420 5) (nlahn 320 15) (nlahn 642 5) (tlewis32 471 15) )) (check-expect (map (make-list-getter 2) COURSES) '(11 5 15 5 15)) (define course-size (make-list-getter 2)) (define course-num (make-list-getter 1)) (define course-prof (make-list-getter 0)) ; or just ...? ; database-y task: How many students are enrolled in 400-level or higher courses? (apply + (map course-size (filter (λ(crs) (> (course-num crs) 400)) COURSES))) ; btw: See `itemgetter` in https://en.wikipedia.org/wiki/K-d_tree#Example_implementation ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; combining functions ; Consider this contract: (define/contract (my-sqrt x) (-> (and/c positive? real?) (and/c positive? real?)) (sqrt x)) (my-sqrt 7) ; What is `and/c` ? ; What is its signature? ; Let's write it ourself! (Just call it `and/f`) (define/contract (and/f f1 f2) (-> (-> any? boolean?) (-> any? boolean?) (-> any? boolean?)) (lambda (x) (and (f1 x) (f2 x)))) ; stub ; Of course, my-sqrt can take 0 *or* positive reals -- i.e. non-negative reals: (define/contract (my-sqrt-v2 x) (-> (and/c (or/c positive? zero?) real?) (and/c (not/c negative?) real?)) (sqrt x)) (my-sqrt-v2 0) ; Your task: write `non` (define/contract (non f) (-> (-> any? boolean?) (-> any? boolean?)) (lambda(x) (not (f x)))) ; a stub (check-expect ((non negative?) 3) #true) (check-expect ((non negative?) 0) #true) (check-expect ((non negative?) -3) #false) ;;;;;;;;;;;;;;;;;;; ; compose (define (compose f1 f2) ;(-> (-> U V) (-> T U) (-> T V)) (λ(x) (f1 (f2 x))) (check-expect ((compose add1 sqr) 3) 10) (check-expect ((compose (make-adder 5) sqr) 3) 14) (check-expect ((compose string-length number->string) 7892) 4) ; apply2x (check-expect ((apply2x sqrt) 81) 3) ; apply3x (check-expect ((apply2x sub1) 81) 78) ; apply-n-times (check-expect ((apply-n-times 10 sub1) 81) 71) (check-expect ((apply-n-times 10 (make-adder 2)) 81) 101) ;;;;;;;;;;;;;;;;;;;;; currying ; we've seen make-adder: (check-expect (map (make-adder 10) '(77 82 73 90)) '(87 92 83 100)) ; This is an eample of *currying* a function. ; How about a curried 'substring': you provide the start/stop indices, ; and return a function that will remove the indicated slice of a string: (check-expect ((substring-curried 2 5) "abcdefg") "cde") (check-expect (map (substring-curried 2 5) '("ibarland" "nlahn" "tlewis32" "aecarter")) (map symbol->string '(arl ahn ewi car))) ; let's write `curry` ourselves! To curry a function of two args, ; we make a function which takes the 1st arg right now, ; and return a function which takes the 2nd arg. (check-expect ((my-curry - 10) 3) 7) (check-expect (map (my-curry - 10) '(33 22 11)) '(23 12 01)) (define (my-curry f arg1) add1) |# (require racket/function) ; BTW: ; (define (make-list-getter n) (curryr list-ref n)) ; or just (define make-list-getter-v2 (curryr list-ref)) ((make-list-getter-v2 3) '(a b c d e f g))