Friend gave me this problem to solve as a way for me to learn Scheme: E::= (λ VE) | (EE) | V with V=variable and write a Scheme function freeVariables
which takes the free variables. For example:
Input = (freeVariables '(λ f (λ x (f ((t g) g)))))
Output = (t g)
However I have the code complete as shown below with logic done. But this is what happens when I add an input:
Input = (freeVariables'(λ f (λ x (f ((t g) g)))))
Output = set-elts: contract violation
expected: set?
given: x
What exactly is wrong with the code I have created? What does the output above mean? And are there any possible fixes? Everything is below Code, logic behind it and debugger.
#lang scheme
(require data/set)
(define (freeVariables exp)
(cond [(null? exp) '()]
[(symbol? exp) (list exp)]
[(eq? (car exp) 'λ)
(let ((variables (cadr exp))
(body (caddr exp)))
(set-difference (freeVariables body) variables))]
[else (apply append (map freeVariables exp))]))
So the logic would work is this:
Thank you and kind regards
Input = (freeVariables'(λ f (λ x (f ((t g) g)))))
Output = set-elts: contract violation
expected: set?
given: x
The grammar in the question only allows for (λ x...)
λ-expressions, with just one parameter.
This means you have a variable
x
, not a list of variables
, to handle.
Thus, write
(let ((var (cadr exp)) ; singular
....
to get that variable, and if you need to have a list of symbols to pass to set-difference
, you need to create that list, using (list var)
instead of your variables
.
The error message indicates that a "contract" has been violated, ie a piece of code's expectations about one of its argument's type have not been met.
Specifically it says that a function set-elts
, apparently called somehow by set-difference
, expects one of its arguments to answer to the predicate set?
, but it does not.
It also indicates x
as the culprit, which is just a symbol inside your test expression. In your case, set?
probably means lists, ie (list 'x)
could pass the muster. If not, try (list->seteq (list var))
.
Another problem with your code is its use of append
, which breaks the abstraction. Use set-union
instead.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.