Я просто играю с NFA для распознавания строк. У меня есть макрос, который создает функцию, которая потребляет ввод и передает остальное некоторым другим функциям. Поскольку в моем графике NFA могут быть петли, я использую letrec, чтобы собрать все вместе. Вот код (тестировался в PLT-Scheme):
(define-syntax-rule (match chars next accepting)
; a function that consumes a list of chars from a list l.
; on success (if there's more to do) invokes each of next on the remainder of l.
(lambda (l)
(let loop ((c chars) (s l))
(cond
((empty? c)
(cond
((and (empty? s) accepting) #t)
(else
(ormap (lambda (x) (x s)) next))))
((empty? s) #f)
((eq? (car c) (car s))
(loop (cdr c) (cdr s)))
(else #f)))))
; matches (a|b)*ac. e .g. '(a a b b a c)
(define (matches? l)
(letrec
([s4 (match '( ) '() #t)]
[s3 (match '(c) `(,s4) #f)]
[s2 (match '(a) `(,s3) #f)]
[s1 (match '( ) `(,s2 ,s5) #f)]
[s5 (match '( ) `(,s6 ,s7) #f)]
[s6 (match '(a) `(,s8) #f)]
[s7 (match '(b) `(,s8) #f)]
[s8 (match '( ) `(,s1) #f)])
(s1 l)))
(matches? '(a c))
(matches? '(a b b b a c))
(matches? '(z a b b b a c))
А что, если бы у меня была простая структура данных для представления моей NFA, например, список списков. например
'((s4 () () #t)
(s3 (c) (s4) #f)
...)
Мой вопрос: Как мне превратить этот список в бывшее заявление letrec? Я не очень хорошо разбираюсь в макросах и понимаю, что мне, вероятно, не следует использовать eval.
match
должен быть макросом, а не обычной функцией? - person Jérémie Koenig   schedule 13.12.2009