traffic_light.ry
module traffic_light
purpose: A traffic light as a state machine driven by timer and emergency events.
import std.console
public type Light is one of
purpose: The colour the light shows.
Red
Green
Yellow
FlashingRed
can ToText
end
public type Event is one of
purpose: Something that can change the light.
TimerExpired
EmergencyDeclared
EmergencyCleared
end
public function next_light(current: Light, event: Event) returns Light
purpose: The light shown after the event; an emergency overrides the normal cycle.
tags: state-machine, traffic
example: next_light(current: Red, event: TimerExpired) is Green
example: next_light(current: Green, event: TimerExpired) is Yellow
example: next_light(current: Yellow, event: TimerExpired) is Red
example: next_light(current: Green, event: EmergencyDeclared) is FlashingRed
example: next_light(current: FlashingRed, event: TimerExpired) is FlashingRed
example: next_light(current: FlashingRed, event: EmergencyCleared) is Red
match event
when EmergencyDeclared then return FlashingRed
when EmergencyCleared then return Red
when TimerExpired then
match current
when Red then return Green
when Green then return Yellow
when Yellow then return Red
when FlashingRed then return FlashingRed
end
end
end
public function run_sequence(start: Light, events: List of Event) returns List of Light
purpose: Every light shown while the events are applied in order, one entry per event.
example: run_sequence(start: Red, events: [TimerExpired, TimerExpired]) is [Green, Yellow]
example: run_sequence(start: Red, events: []) is []
let mutable current be start
let mutable shown: List of Light be []
for each event in events
change current to next_light(current: current, event: event)
change shown to shown.append(current)
end
return shown
end
public function main() needs console
purpose: Print the lights of a short sequence with one emergency in the middle.
let events be [TimerExpired, TimerExpired, EmergencyDeclared, TimerExpired, EmergencyCleared]
for each light in run_sequence(start: Red, events: events)
console.print(light.to_text())
end
end