CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(require rackunit)
(check-true (member? "d" (list "a" "b" "c" "d")))
(check-false (member? "f" (list "a" "b" "c" "d")))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(require rackunit)
(check-true (member? "d" (list "a" "b" "c" "d")))
(check-false (member? "f" (list "a" "b" "c" "d")))
(define (member? x l)
(match l
[(list) #f]
[(cons h l)
(define result (member? x l))
`(or (equal? x h) result)`]))
def member(x, l):
for h in l:
if h == x:
return True
return False
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(require rackunit)
(check-true (member? "d" (list "a" "b" "c" "d")))
(check-false (member? "f" (list "a" "b" "c" "d")))
(define (member? x l)
(match l
[(list) #f]
[(cons h _) #:when (equal? x h) #t]
[(cons _ l) (member? x l)]))
def member(x, l):
for h in l:
if h == x:
return True
return False
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(require rackunit)
(check-true (string-prefix? "Racket" "R")) ; available in standard library
(check-true (match-prefix? "R" (list "foo" "Racket")))
(check-false (match-prefix? "R" (list "foo" "bar")))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(require rackunit)
(check-true (string-prefix? "Racket" "R")) ; available in standard library
(check-true (match-prefix? "R" (list "foo" "Racket")))
(check-false (match-prefix? "R" (list "foo" "bar")))
(define (match-prefix? p l)
(match l
[(list) #f]
[(cons h _) #:when (string-prefix? h p) #t]
[(cons _ l) (match-prefix? p l)]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
; Example 1
(define (member? x l)
(match l
[(list) #f]
[(cons h _) #:when `(equal? h x)` #t]
[(cons _ l) (member? x l)]))
; Example 2
(define (match-prefix? p l)
(match l
[(list) #f]
[(cons h _) #:when `(string-prefix? h p)` #t]
[(cons _ l) (match-prefix? p l)]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
; Example 1
(define (member? x l)
(match l
[(list) #f]
[(cons h _) #:when `(equal? h x)` #t]
[(cons _ l) (member? x l)]))
; Example 2
(define (match-prefix? p l)
(match l
[(list) #f]
[(cons h _) #:when `(string-prefix? h p)` #t]
[(cons _ l) (match-prefix? p l)]))
(define (exists? found? l)
(match l
[(list) #f]
[(cons h _) #:when `(found? h)` #t]
[(cons _ l) (exists? found? l)]))
; Example 1
(define (member? `x` l)
(exists?
(lambda (y) (equal? `x` y)) l))
; Example 2
(define (match-prefix? `x` l)
(exists?
(lambda (y) (string-prefix? y `x`))) l)
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(require rackunit)
(check-equal? (list 1 3 4) (remove-0s (list 0 1 3 0 4)))
(check-equal? (list 1 2 3) (remove-0s (list 1 2 3)))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(require rackunit)
(check-equal? (list 1 3 4) (remove-0s (list 0 1 3 0 4)))
(check-equal? (list 1 2 3) (remove-0s (list 1 2 3)))
(define (remove-0s l)
(match l
[(list) (list)]
[(cons h l) #:when (not (equal? h 0))
(cons h (remove-0s l))]
[(cons _ l) (remove-0s l)]))
def remove_0s(l):
result = []
for h in l:
if h != 0:
result.append(h)
return result
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (remove-0s l)
(match l
[(list) (list)]
[(cons h l) #:when (not (equal? h 0))
(cons h (remove-0s l))]
[(cons _ l) (remove-0s l)]))
(define (filter keep? l)
(match l
[(list) (list)]
[(cons h l) #:when `(keep? h)`
(cons h (filter keep? l))]
[(cons _ l) (filter keep? l)]))
;; Usage example
(define (remove-0s l)
(filter
(lambda (x) (not (equal? x 0))) l))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
Implement function (append l1 l2) that appends two lists
together.
(check-equal?
(append (list 1 2) (list 3 4))
(list 1 2 3 4))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
Implement function (append l1 l2) that appends two lists
together.
(check-equal?
(append (list 1 2) (list 3 4))
(list 1 2 3 4))
(define (append l1 l2) ; l2 = (list 4 5 6)
(match l1 ; l1 = (list 1 2 3)
[(list) `l2`]
[(cons h l1) ; h = 1 l1 = (list 2 3)
(define result (append l1 l2)) ; result = (append '(2 3) '(4 5 6))
; result = (list 2 3 4 5 6)
`(cons h result)`]))
; output = (list 1 2 3 4 5 6)
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(list) (handle-base)(cons h l) (handle-step)(define (rec l)
(match l
[(list) `handle-base`]
[(cons h l)
(define result (rec l))
`(handle-step h result)`]))
(define (map f l)
(match l
[(list) `(list)`]
[(cons h l)
(define result (map f l))
`(cons (f h) result)`]))
; = (handle-step h result)
(define (append l1 l2)
(match l1
[(list) `l2`]
[(cons h l1)
(define result (append l1 l2))
`(cons h result)`]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
map as the order of side-effects may matter.map invokes f from left-to-right.map invokes f from right-to-left.foldrf before recursing(map displayln (list 1 2 3)) on either version to observe the difference(define (map f l)
(match l
[(list) (list)]
[(cons h l)
(define result (map f l))
(cons `(f h)` result)]))
(define (map f l)
(match l
[(list) (list)]
[(cons h l)
`(define x (f h))`
(define result (map f l))
(cons `x` result)]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (exists? found? l)
(match l
[(list) #f]
[(cons h _) #:when (found? h) #t]
[(cons _ l) (exists? found? l)]))
(define (exists? found? l)
(match l
[(list) `#f`]
[(cons h l)
(define result (exists? found? l))
`(or (found? h) result)`]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (filter keep? l)
(match l
[(list) (list)]
[(cons h l) #:when (keep? h)
(cons h (filter keep? l))]
[(cons _ l) (filter keep? l)]))
(define (filter keep? l)
(match l
[(list) `(list)`]
[(cons h l)
(define result (filter keep? l))
`(if (keep? h)`
`(cons h result) result)`]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (rec l)
(match l
[(list) `base-case`]
[(cons h l)
(define result (rec l))
`(handle-step h result)`]))
(define (foldr `handle-step` `base-case` l)
(match l
[(list) `base-case`]
[(cons h l)
(define result (foldr handle-step base-case l))
`(handle-step h result)`]))
# In Python
def foldr(handle_step, base_case, l):
result = base_case
for h in reversed(l):
result = handle_step(h, result)
return result
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (map f l)
(match `l`
[(list) `(list)`]
[(cons h l)
(define result (map f l))
`(cons (f h) result)`]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (map f l)
(match `l`
[(list) `(list)`]
[(cons h l)
(define result (map f l))
`(cons (f h) result)`]))
(define (map f l)
(foldr
; step: how do you build the next result
(lambda (h result) `(cons (f h) result)`)
; what to return when the list is empty
`(list)`
; iterate/match over l
`l`))
# Python pseudo-code
result = []
for h in reversed(l):
# result = cons(f(h), result)
result.append(f(h))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (append l1 l2)
(match `l1`
[(list) `l2`]
[(cons h l1)
(define result (append l1 l2))
`(cons h result)`]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (append l1 l2)
(match `l1`
[(list) `l2`]
[(cons h l1)
(define result (append l1 l2))
`(cons h result)`]))
(define (append l1 l2)
(foldr
; step: add the element to the list being built
(lambda (h result) `(cons h result)`)
; base-case: start with list l2
`l2`
; iterate/match over l1
`l1`))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (filter keep? l)
(match `l`
[(list) `(list)`]
[(cons h l)
(define result (filter keep? l))
`(if (keep? h) (cons h result) result)`]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (filter keep? l)
(match `l`
[(list) `(list)`]
[(cons h l)
(define result (filter keep? l))
`(if (keep? h) (cons h result) result)`]))
(define (filter keep? l)
(foldr
; handle-step
(lambda (h result) `(if (keep? h) (cons h result) result)`)
; base-case
`(list)`
; iterate/match over l
`l`))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (exists? found? l)
(match `l`
[(list) `#f`]
[(cons h l)
(define result (exists? found? l))
`(or (found? h) result)`]))
CS450 ☽ foldr, looping last-to-first ☽ Lecture 07 ☽ Tiago Cogumbreiro
(define (exists? found? l)
(match `l`
[(list) `#f`]
[(cons h l)
(define result (exists? found? l))
`(or (found? h) result)`]))
(define (exists? found? l)
(foldr
; handle-step
(lambda (h result) `(or (found? h) result)`)
; base-case
`#f`
; iterate over l
`l`))