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