Functor, Natural tranformation, and Monad in Racket

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