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

为什么Haskell代码会出现parse error on input ‘isFileEnd’错误

问题排查与解决

1 解析错误的直接原因

你遇到的parse error on input ‘isFileEnd’是Haskell缩进规则不满足导致的:
where关键字后的绑定函数readDataFrom的do块内的代码,缩进必须比readDataFrom的起始位置更靠右,你原代码里isFileEnd所在行的缩进级别低于readDataFrom的起始位置,编译器无法识别这是readDataFrom内部的代码,直接抛出解析错误。

2 其他隐藏的类型/逻辑错误

除了缩进外,你的代码还有多处不匹配的问题:

  • 签名中func的类型是Handle -> IO a,但你调用时传入的是hGetLine返回的String类型的info,类型不匹配
  • readTableFile签名声明返回IO [a],但你当前实现没有收集func的执行结果,反而返回的是IO ()
  • withFile会在传入的lambda执行完成后自动关闭文件句柄,你尝试把withFile的返回值绑定到fileHandle没有任何意义,lambda执行完成后句柄已经失效
  • readDataFrom当前返回的是IO String,和你需要的返回列表的逻辑不符

3 修正后的完整代码

import System.IO (Handle, withFile, ReadMode, hIsEOF, hGetLine)

-- 调整func的类型为String -> IO a,匹配你传入每行字符串调用的逻辑
readTableFile :: String -> (String -> IO a) -> IO [a]
readTableFile file func = withFile file ReadMode readDataFrom
  where 
    -- readDataFrom缩进级别高于where关键字
    readDataFrom :: Handle -> IO [a]
    readDataFrom fileHandle = do
      -- do块内代码缩进高于readDataFrom的起始位置
      isFileEnd <- hIsEOF fileHandle
      if isFileEnd 
        then return []
        else do
          info <- hGetLine fileHandle
          res <- func info
          rest <- readDataFrom fileHandle
          return (res : rest)

4 使用示例

如果你需要打印每行内容的同时收集长度,可以这么调用:

main :: IO ()
main = do
  lineLengths <- readTableFile "test.txt" (\line -> do
    putStrLn line
    return $ length line
    )
  print lineLengths

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 22:54:07