该name2 <-
语法是 do-notation 的一部分,只能在do
块内使用。它也不是变量赋值 - 在引擎盖下它只是创建一个回调函数name2
作为参数
也就是下面的代码:
do
name2 <- monadicOp
...things...
脱糖成
monadicOp >>= (\name2 -> ...things... )
我希望这有助于清楚地表明您不会在 Haskell 中分配或改变它们。
无论如何,要解决您的特定问题,您可以做的就是使用 if-then-else (实际上相当于?:
三元运算符)并返回适当的值。例如,以下函数使用递归来一次又一次地询问名称,直到它对结果满意为止
getNonEmptyName :: IO String
getNonEmptyName = do
name <- getName
if null name --note: indenting if statements in do blocks is tricky
then getNonEmptyName
else (return name)
或者,没有 do 符号糖:
getNonEmptyName = getName >>= (\name -> if (null name) then getNonEmptyName else (return name) )
这可能与您习惯的有所不同,但我想您应该能够在了解其工作原理后清除事物。基本上getNonEmptyName
是 type IO String
,这意味着它是一个 IO 动作 IO 动作,它在运行时产生一个字符串。if-then-else 部分也应该评估为一个IO String
值,因为它的值将是 getNonEmptyName 的返回值。这一切正常,因为首先我们对 getNonEmptyName 进行递归调用(并根据需要提供 IP 字符串值),在 else 分支中,我们使用返回函数将常规字符串值(名称)提升为 IO 字符串。