【问题标题】:How to use let inside if block inside a do notation in haskell如何在haskell的do符号内使用let inside if块
【发布时间】:2018-04-29 22:37:11
【问题描述】:

我收到以下代码错误:

main = do
    putStrLn "Enter parameter"
    parameter <- getLine
    if head parameter == "c" then
        let object = getObject parameter
        print object
    else
        putStrLn "Error, try again"
        main

我得到的错误是:

parse error on input `print'

尝试打印对象时。如果我改为尝试打印函数的值而不保存它,让它工作得很好,但我需要保存对象以供以后使用。

语法应该如何使它工作?

同样在“其他”部分我得到以下错误:

The function `putStrLn' is applied to two arguments,
    but its type `String -> IO ()' has only one
    In the expression: putStrLn "Error" main

它认为我尝试运行 main 作为 putStrLn 的参数,但我真正想做的是首先显示错误,然后再次运行 main。我怎样才能解决这个问题?

提前致谢!

【问题讨论】:

  • 语法是let .. in expr,所以你需要let object = getObject parameter in print object
  • 啊,太简单了!我认为“in”只在do符号之外使用。完美运行,谢谢!

标签: haskell if-statement let


【解决方案1】:

您的代码存在一些问题。

首先,存在解析错误。有两种方法可以解决此问题。正如@Lee 指出的那样,一种方法是使用 let .. in 块。

let object = getObject parameter
in  print object

或者,我们可以在 else 子句中开始另一个 do 块:

then do
   let object = getObject parameter
   print object

其次,您将一个字符串的头部与另一个字符串进行比较:

head parameter == "c"

getLine 返回一个字符串,所以字符串的头部是一个字符。我们可以把它改成

head parameter == 'c'

最后,您尝试在一个块中执行两个语句,类似于 else 子句中的之前:

else 
    putStrLn "Error, try again"
    main

如果你想将多个语句链接在一起,我们必须像以前一样使用 do 块:

else do
    putStrLn "Error, try again"
    main

把它们放在一起:

main = do
    putStrLn "Enter parameter"
    parameter <- getLine
    if head parameter == 'c' then do
        let object = getObject parameter
        print object
    else do
        putStrLn "Error, try again"
        main

【讨论】:

  • 操作!我做了一个小的简化,以便更容易阅读代码。该参数被拆分为带有“单词”的字符串列表,因此头部标识了命令。不过谢谢!现在一切正常!
  • @SebastianPaulsen 好吧,我认为这可能是一个错字。乐于助人!
  • 如果我想稍后在代码中使用“对象”并在其上运行函数,我该怎么做?我无法访问 if 语句之外的对象,也无法在 main 开头创建“全局”变量,因为变量无法更改。如何克服这个问题?
  • @SebastianPaulsen 您可以使用 state monad 或类似的东西,也可以尝试构建程序以仅在 if 语句中完成工作。此外,由于懒惰,您可以在 if 语句之外分配它,并且只有在您以后使用它时才会对其进行评估。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
相关资源
最近更新 更多