You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell代码报parse input error错误的原因排查咨询

Haskell语法错误排查:parse error on input 'addfunc'

问题说明

我编写了一个Haskell程序,功能是:输入英文单词形式的数字(如"one""two"等),输入"sum"时输出当前总和并继续运行,输入"end"时输出最终总和并退出程序。但代码出现了解析错误,报错位置在addfunc l;行,错误信息为:

error: parse error on input 'addfunc'
 17.    addfunc l;

尝试调整空格数量或移除该行上方的分号后,错误依然存在,想知道是不是缩进问题导致的。

原代码

main = addfunc 0


addfunc :: Int -> IO ()
addfunc l = do
 {
  input <- getLine;
  let n = myStrToI input
  ; if n == -2 
    then do {
          putStrLn("The final sum is: " ++ show (l));
          return ();            
          }
    else if n == -1 
     then 
           putStrLn("The current sum is: " ++ show(l));
           addfunc l;     <--Error Here       
    else  addfunc (n+l)
 }

myStrToI :: [Char] -> Int
myStrToI l
  | l == "zero" = 0
  | l == "one" = 1
  | l == "two" = 2
  | l == "three" = 3
  | l == "four" = 4
  | l == "five" = 5
  | l == "six" = 6
  | l == "seven" = 7
  | l == "eight" = 8
  | l == "nine" = 9
  | l == "sum" = -1
  | l == "end" = -2

错误原因与修复方案

这个错误确实和do块的语法规则有关——你混合使用了大括号+分号、缩进两种do块写法,同时在else if n == -1 then分支下没有用do包裹多个IO动作,导致编译器无法正确解析。

Haskell的if-then-else要求then和else后面的表达式类型必须一致,这里都是IO ()类型。如果一个分支里有多个IO动作(比如先打印再递归调用),必须用do把这些动作组合成一个IO ()表达式。

另外,Haskell社区更推荐用缩进风格写do块,避免大括号和分号带来的语法混乱。下面是修复后的代码:

main = addfunc 0

addfunc :: Int -> IO ()
addfunc l = do
  input <- getLine
  let n = myStrToI input
  if n == -2 
    then do
      putStrLn $ "The final sum is: " ++ show l
      return ()            
    else if n == -1 
      then do
        putStrLn $ "The current sum is: " ++ show l
        addfunc l       
      else addfunc (n + l)

myStrToI :: String -> Int
myStrToI l
  | l == "zero" = 0
  | l == "one" = 1
  | l == "two" = 2
  | l == "three" = 3
  | l == "four" = 4
  | l == "five" = 5
  | l == "six" = 6
  | l == "seven" = 7
  | l == "eight" = 8
  | l == "nine" = 9
  | l == "sum" = -1
  | l == "end" = -2
  | otherwise = 0  -- 可选:处理无效输入,避免运行时崩溃

主要修复点:

  1. 移除了所有不必要的大括号和分号,采用缩进风格组织do块代码,确保每个do块内的语句缩进一致。
  2. 在else if n == -1 then分支后添加了do关键字,把putStrLn和addfunc l两个IO动作组合成一个合法的IO ()表达式。
  3. 将[Char]替换为更易读的String(两者是同义词),并用$运算符简化了putStrLn的写法,减少冗余括号。
  4. 可选添加了| otherwise = 0分支,处理未匹配的输入(比如乱输的单词),避免程序运行时崩溃。

内容的提问来源于stack exchange,提问作者Poseidon9850

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 06:25:21