在haskell中调用after之后赋值

时间:2013-01-08 18:40:18

标签: haskell

在这几行中,错误必须非常小,以至于我无法获得它的支持。

这是我的代码:

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)

2 个答案:

答案 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