FSM actions as functors:
#lang racket
(define state0 'start)
(define (string->char* str) (reverse (string->list str)))
(define transition
(let ([trl*
`([,state0 ,char-alphabetic? name]
[,state0 ,char-alphabetic? name]
[,state0 ,char-numeric? number]
[,state0 ,(curry char=? #\() lparen]
[,state0 ,(curry char=? #\)) rparen]
[name ,char-alphabetic? name]
[name ,char-numeric? name]
[number ,char-numeric? number])])
(λ (ch state)
(or
(for/or ([trl (in-list trl*)])
(match-define `[,s ,p? ,e] trl)
(and (symbol=? state s) (p? ch) e))
'error))))
(define (action ch* state)
(if (null? ch*)
state
(transition (car ch*) (action (cdr ch*) state))))
(define (recognizer str) (action (string->char* str) state0))
(for/list ([str (in-list '("abc112" "112" "(" ")"))]) (recognizer str)) ; '(name number lparen rparen)
(define ∘ compose)
(define ∘𝒞𝒽 append)
(define F (curry action))
;; input string: "abc112"
((F (∘𝒞𝒽 (string->char* "112") (string->char* "abc"))) state0) ; 'name
((∘ (F (string->char* "112")) (F (string->char* "abc"))) state0) ; 'name
;; input string: "112"
((F (∘𝒞𝒽 (string->char* "11") (string->char* "2"))) state0) ; 'number
((∘ (F (string->char* "11")) (F (string->char* "2"))) state0) ; 'number