Есть две проблемы:
- интенсиональное равенство
eq?
вместо экстенсионального равенства, такого как equal?
или string=?
- сравнение строки / символа вместо сравнения символа / символа или строки / строки
Вы используете eq?
, что всегда вызывает у меня подозрения. eq?
использует "интенсиональное" равенство, которое в основном является равенством указателя, означая, что строка, которая расположена где-то в памяти, не обязательно будет eq?
, даже если она имеет те же символы. Вы можете увидеть это с (eq? "abc123" (string-append "abc" "123"))
.
Если вы имеете дело со строками, списками или любыми другими данными, которые «содержат» вещи, вам следует избегать eq?
. Вместо этого вы должны использовать «экстенсиональный» предикат равенства, такой как equal?
, или, что еще лучше, предикат, специфичный для ожидаемых вами типов значений, например, string=?
. Вот как они ведут себя лучше, чем eq?
:
> (eq? "abc123" (string-append "abc" "123"))
#f
> (equal? "abc123" (string-append "abc" "123"))
#t
> (string=? "abc123" (string-append "abc" "123"))
#t
Поскольку вы сравниваете, используя строки "p"
и "l"
, я смогу заменить eq?
на string=?
в вашем коде:
(: prefixes : (Listof String) (Listof String) -> (Listof String))
(define (prefixes lis em)
(cond
[(and (string=? (string-ref (first lis) 0) "p") (string=? (string-ref (first lis) 1) "l"))
(cons (first lis) em)]
[else
(prefixes (rest lis) em)]))
Однако это выявляет вторую проблему, которую я заметил только после появления сообщения об ошибке:
string=?: contract violation
expected: string?
given: #\y
argument position: 1st
other arguments...:
"p"
string=?
не работает, потому что его первый аргумент, результат string-ref
, является символом (например, #\y
), а не строкой. Чтобы это исправить, используйте char=?
вместо string=?
и сравните с символами #\p
и #\l
вместо строк "p"
и "l"
.
(: prefixes : (Listof String) (Listof String) -> (Listof String))
(define (prefixes lis em)
(cond
[(and (char=? (string-ref (first lis) 0) #\p) (char=? (string-ref (first lis) 1) #\l))
(cons (first lis) em)]
[else
(prefixes (rest lis) em)]))