I have the following code for an API for manipulating a robot:
data Direction = Left | Right
forward :: IO ()
blocked :: IO Bool
turn :: Direction -> IO ()
I am trying to understand two programs that will move the robot forward unless it is blocked by an obstacle, in which case, the robot should turn in the Right direction.
However, I am not sure what is the difference is between the following two programs:
-- program 1
robot = do
detected <- blocked
if detected
then turn Right
else forward
robot
-- program 2
robot = do
detected <- blocked
if detected
then turn Right
robot
else forward
robot
The line detected <- blocked
takes the boolean value out of the IO. If the condition if detected
evaluates as true, then the robot turns Right, otherwise the robot moves forward. In program 1 the function robot is called again after moving the robot either right or forward. In program 2, the function robot is called directly after turning right or moving forward.
I am not sure what the difference is between calling robot after the if-else
statements (in program 1) versus calling it in the then
and else
case in program 2. Am I correct in saying that these two programs are equivalent? Any insights are appreciated.
You are correct in saying that these two programs are equivalent. More generally, if cond then (x >> action) else (y >> action)
is equivalent to (if cond then x else y) >> action
. This is a consequence of the fact that f (if cond then x else y) = if cond then (f x) else (f y)
; if you take f = (>> action)
you get the equivalence for monads.