【发布时间】:2019-12-04 09:33:54
【问题描述】:
我有以下代码用于操作机器人的 API:
data Direction = Left | Right
forward :: IO ()
blocked :: IO Bool
turn :: Direction -> IO ()
我正在尝试了解两个程序,它们将使机器人向前移动,除非它被障碍物阻挡,在这种情况下,机器人应该朝正确的方向转动。
但是,我不确定以下两个程序之间有什么区别:
-- 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
detected <- blocked 行将布尔值从 IO 中取出。如果条件if detected 评估为真,则机器人向右转,否则机器人向前移动。在程序 1 中,机器人功能在向右或向前移动后再次被调用。程序2中,函数robot在右转或前进后直接调用。
我不确定在 if-else 语句(在程序 1 中)之后调用机器人与在程序 2 中的 then 和 else 案例中调用它有什么区别。我说这两个是否正确程序是等价的吗?任何见解都值得赞赏。
【问题讨论】:
-
第二种情况不需要
do turn Right; robot吗(;代表换行)? -
为什么一定要右转;程序二的机器人?是否需要它,因为为了将多个 IO 操作粘合在一起?
-
是的,对于您的版本,我不确定它为什么会编译。
-
@ceno980 因为 if/then/else 的 then 和 else 部分可以是任意表达式,所以它们使用普通的 Haskell 表达式语法。它们不会自动成为
do块语法,因为整个 if/then/else 恰好发生在 do 块中。您想要对两个 IO 操作进行排序。一种方法是将它们写在do块的不同行上。在普通的表达式语法中,将它们写在多行上并不能做到这一点。它与turn Right robot在一行上的含义相同。如果你想要do语法,你需要开始一个新的do块。 -
怎么知道robot是一个IO动作?是因为在do块中使用了IO动作吗?
标签: haskell functional-programming monads equivalence do-notation