Я новичок, работающий через HTDP2 (Felleisen et al.) Самостоятельно, но застрял в вопросе № 380 главы IV - Переплетенные данные. Проблема в контексте создания DSL, но я сначала повторно ознакомился с общим симулятором FSM и получил следующий код:
; An FSM is a [List-of 1Transition]
; A 1Transition is a list of two items:
; (cons FSM-State (cons FSM-State '()))
; An FSM-State is a String that specifies a color
; data examples
(define fsm-traffic
'(("red" "green") ("green" "yellow") ("yellow" "red")))
; FSM FSM-State -> FSM-State
; matches the keys pressed by a player with the given FSM
(define (simulate state0 transitions)
(big-bang state0 ; FSM-State
[to-draw
(lambda (current)
(overlay (text current 12 "black")
(square 100 "solid" current)))]
[on-key
(lambda (current key-event)
(find transitions current))]))
; [X Y] [List-of [List X Y]] X -> Y
; finds the matching Y for the given X in alist
(define (find alist x)
(local ((define fm (assoc x alist)))
(if (cons? fm) (second fm) (error "not found"))))
Проблема тогда сформулирована следующим образом:
Переформулируйте определение данных для 1Transition, чтобы можно было ограничить переходы определенными нажатиями клавиш. Попробуйте сформулировать изменение так, чтобы find
продолжал работать без изменений. Что еще нужно изменить, чтобы заставить работать всю программу? Какая часть рецепта дизайна дает ответ (ы)? См. Упражнение 229. Исходное утверждение упражнения.
В упражнении 229 вводится определение типа структуры для отслеживания состояний и переходов, но, поскольку в заявлении о проблеме содержится просьба остаться в рамках предоставленной функции find
, мне трудно найти аналогичное определение типа структуры. Вместо этого я придумал следующее определение данных:
; An FSM is a [List-of Transition]
; A Transition is a two-item list of the following form:
; (cons FSM-State (cons (cons KeyEvent (cons FSM-State '()))'()))
; data example
(define fsm-traffic (list (list "red" (list "r" "green"))
(list "green" (list "g" "yellow"))
(list "yellow" (list "y" "red"))))
Следовательно, вызывая (find fsm-traffic "green")
Я получаю (list "g" "yellow")
Я изменил предложение on-key
следующим образом:
(lambda (current key-event)
(if (string=? key-event (first (first (rest (first transitions)))))
(second (find transitions current))
(error "invalid input")))
Теперь, если я запускаю программу с * 1019, * отображается State0, и если я нажимаю «r», он переходит в «зеленое» состояние FSM, но затем не принимает «g» для перехода в следующее состояние и т. Д. на.
Если я начинаю мировую программу с (simulate "yellow" fsm-traffic)
, то FSM-состояние «желтый» отображается, но оно не переходит в какое-либо другое состояние (включено условие error
); аналогично с «зеленым» в качестве исходного состояния.
Моя догадка заключается в том, что, поскольку я сначала определил fsm-traffic
с "красным" состоянием, он принимает свой вход для перехода к "зеленому", но поскольку этого не происходит с другими состояниями big-bang
не "жонглирует" transitions
параметр справа. Но я просто не знаю, как это исправить. Я также не знаю, ошибся ли я с самого начала определения данных.
Заранее спасибо за помощь.
P.D. пожалуйста, дайте мне знать, если я следовал правилам публикации на stackoverflow (это мой первый пост :).