I'm working through a textbook on programming languages, and one of the exercises was to make a function in Scheme that flips tuples in a list. Here's my code:
; invert : Listof(List(Int,Int)) -> Listof(List(Int,int))
; usage: (invert '((a 1) (a 2) (1 b) (2 b))) -> ((1 a) (2 a) (b 1) (b 2))
(define invert
(lambda (lst)
(if (null? lst)
'()
(cons
(flip (car lst))
(invert (cdr lst))))))
; flip : List(Int,Int) -> List(Int,int)
; usage: (flip '(a 1)) -> (1 a)
(define flip
(lambda (tuple)
(if (not (eqv? (length (tuple)) 2))
(eopl:error 'flip
"Tuple is not length 2~%")
(cons (cdr tuple) (car tuple)))))
I tried testing my program in chez-scheme. When I use the test case in the usage comment, I get this error: Exception: attempt to apply non-procedure (a 1)
. I've never worked with Scheme before, so I'd greatly appreciate any help and advice. Thanks!
You have a coupe of errors in flip
, this should fix them:
(define flip
(lambda (tuple)
(if (not (= (length tuple) 2))
(eopl:error 'flip "Tuple is not length 2~%")
(list (cadr tuple) (car tuple)))))
In particular:
(tuple)
. We must not surround variables with ()
, unless they're procedures that we intend to call.=
for comparing numbers, not eqv?
.(cons (cdr tuple) (car tuple))
there are two issues, for building a list of two elements we use list
, not cons
. And for accessing the second element we use cadr
, not cdr
- you should read a bit about how cons
, car
and cdr
are used for building lists.Notice that there's a simpler way to solve this problem if we use map
; I'll skip error checking for simplicity:
(define (invert lst)
(map (lambda (tuple) (list (cadr tuple) (car tuple)))
lst))