【问题标题】:Why am I getting a parse error on the closing bracket in Haskell?为什么我在 Haskell 的右括号上出现解析错误?
【发布时间】:2021-02-18 15:42:22
【问题描述】:
printExclamation :: Int -> IO()
pintExclamation n = do {
                        n <- getInt;
                        if n == n;
                        then return !
                      } 

编译时,我得到“parse error on input `}'”。我不知道为什么。

【问题讨论】:

  • 没有else。此外,! 没有返回值的定义,您在 do 块中同时使用 n 作为参数和变量。
  • 我知道 if n == n 什么都不做,但我想先编译一下,然后才能弄清楚该怎么做
  • 在 Haskell 中,if ... then ... else ... 总是有一个else 块,因为if ... then ... else ... 不是 语句,而是表达式。与(大多数)命令式语言相比,这只是函数应用程序的语法糖,例如,您可以将其替换为 ifThenElse
  • 我会在哪里定义输出很多!取决于 n?
  • @Sattoshi7:因为类型是IO (),所以只能返回一个单位(),不能返回值……

标签: function parsing haskell io return


【解决方案1】:

解析器需要一个else 块。在 Haskell 中,写 if … then … 没有 else … 块是没有意义的。 if … then … else … 子句不是语句,而是表达式。如果条件为True,将使用then … 块中的值的表达式,否则使用else … 块中的部分。

因此你可以这样写:

printExclamation :: Int -> IO()
printExclamation m = do
    n <- readLn
    if m == n
      then return ()
      else return ()

注意return :: Monad m =&gt; a -&gt; m a 会以一元类型注入一个值。因此,它不等同于(大多数)命令式语言中的 return 语句将“停止流经函数”。

如果得到的数字nm相同,可以使用putStrLn :: String -&gt; IO ()打印感叹号:

printExclamation :: Int -> IO()
printExclamation m = do
    n <- readLn
    if m == n
      then putStrLn "!"
      else return ()

然后我们可以测试这个函数:

Prelude> printExclamation 4
4
!
Prelude> printExclamation 3
4
Prelude>

【讨论】:

  • 我现在明白了。谢谢你。虽然编译时不打印!只有一个空行,按回车后我收到这条消息“*** Exception: user error (Prelude.readIO: no parse)”
  • @Satoshi7:那是因为您可能在标准输入已关闭时运行该程序。 readLn 尝试从标准输入通道读取数据。
  • 我明白了:前奏曲> printExclamation 4 4 ! ,当我想得到!!!! - 相同的数量!作为我输入的整数
  • @Satoshi7:看看replicate。但是,如果您想返回某些内容,而不是读取/打印,则首先不应使用IO,而应仅使用函数myfunc :: Int -&gt; Int -&gt; String
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-11
  • 2021-11-13
  • 1970-01-01
  • 2012-12-01
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
相关资源
最近更新 更多