在haskell中调用after之后赋值

pig*_*ack -1 haskell

在这几行中,错误必须非常小,以至于我无法得到它.

这是我的代码:

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)

hug*_*omg 9

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.