在这几行中,错误必须非常小,以至于我无法得到它.
这是我的代码:
askName = do
putStr "Type your name: "
name <- getLine
return name
sayHelloTo name = do
when (null name) (name <- askName)
Run Code Online (Sandbox Code Playgroud)
显然它给出了一个错误:
1 of 1] Compiling Main ( test.hs, interpreted )
test.hs:9:30: parse error on input `<-'
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)
有什么建议吗?
编辑1.
如果我写的话也一样:
sayHelloTo name = do
when (null name) (name2 <- askName)
Run Code Online (Sandbox Code Playgroud)
该name2 <-语法是DO-符号的一部分,并且仅可以在内部使用do的块.它也不是一个变量赋值 - 它只是创建一个name2带有参数的回调函数
也就是说,以下代码:
do
name2 <- monadicOp
...things...
Run Code Online (Sandbox Code Playgroud)
desugars into
monadicOp >>= (\name2 -> ...things... )
Run Code Online (Sandbox Code Playgroud)
我希望这有助于说明你不在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)
Run Code Online (Sandbox Code Playgroud)
或者,没有做符号糖:
getNonEmptyName = getName >>= (\name -> if (null name) then getNonEmptyName else (return name) )
Run Code Online (Sandbox Code Playgroud)
这可能与你习惯的有点不同,但我想你应该能够在得到它如何工作之后清除它.基本上getNonEmptyName是类型IO String,这意味着它是一个IO actioin IO动作,它在运行时产生一个String.if-then-else部分也应该计算为一个IO String值,因为它的值将是getNonEmptyName的返回值.这一切都可以正常工作,因为在第一次我们对getNonEmptyName进行递归调用(并根据需要提供IP字符串值),而在else分支中,我们使用return函数将常规字符串值(name)提升为IO String.