Created
November 4, 2016 08:10
-
-
Save Horusiath/69f0521e74f713a4c81891333ea35131 to your computer and use it in GitHub Desktop.
Free like a monad
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Distance = float | |
type Angle = float | |
type PenColor = string | |
type TurtleProgram = | |
// (input params) (response) | |
| Stop | |
| Move of Distance * TurtleProgram | |
| Turn of Angle * TurtleProgram | |
| PenUp of (* none *) TurtleProgram | |
| PenDown of (* none *) TurtleProgram | |
| SetColor of PenColor * TurtleProgram | |
type TurtleState = | |
{ color: PenColor; isDrawing: bool } | |
let rec interpret state program = | |
match program with | |
| Stop -> | |
state | |
| Move (dist,next) -> | |
reduceMoves dist state next | |
| Turn (angle,next) -> | |
reduceTurns angle state next | |
| PenUp next -> | |
let newState = { state with isDrawing = false } | |
interpret newState next | |
| PenDown next -> | |
let newState = { state with isDrawing = true } | |
interpret newState next | |
| SetColor (color,next) -> | |
let newState = { state with color = color } | |
interpret newState next | |
and reduceMoves acc state program = | |
match program with | |
| Move(dist, next) -> | |
// combine subsequent moves | |
reduceMoves (acc+dist) state next | |
| _ -> | |
if state.isDrawing then | |
printfn "Turtle drawn line: distance=%f, color=%s" acc state.color | |
else | |
printfn "Turtle moved: distance=%f" acc | |
interpret state program | |
and reduceTurns acc state program = | |
match program with | |
| Turn(angle, next) -> | |
// combine subsequent turns | |
reduceTurns (acc+angle) state next | |
| _ -> | |
printfn "Turtle turned %f degrees" acc | |
interpret state program | |
let drawTriangle = | |
Move(100.0, | |
Turn(120.0, | |
Move(50., // those two moves will be folded | |
Move(50., | |
Turn(120.0, | |
Move(100., | |
Turn(120.0, | |
Stop))))))) | |
interpret {isDrawing = true; color = "Blue" } drawTriangle |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment