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

Teletype类型下编写getLine函数遇编译错误:Char与[Char]类型不匹配

解决Teletype getLine实现的问题

首先看编译错误的直接原因:你把字符(Char)和字符串([Char])搞混了!在Haskell里,单引号包裹的是单个字符(比如'\n'),而双引号包裹的是字符串(比如"\n"是长度为1的字符串)。你的代码里c是Char类型,却和"\n"([Char])做相等比较,这就导致了类型不匹配的错误。

不过除了这个语法问题,你的实现逻辑也有问题:当前代码没有积累读取到的字符,遇到换行就直接返回单个字符,而且还多余地调用了Put c——getLine的功能是读取一行字符并返回字符串,不需要输出读取到的内容。

正确的实现思路

我们需要一个辅助函数来积累已经读取到的字符,因为每次读取一个字符后,需要把它和之前的字符拼接起来,直到遇到换行符。

完整的正确实现代码如下:

data Teletype a = End a | Get (Char -> Teletype a) | Put Char (Teletype a)

getLine :: Teletype String
getLine = getLineHelper ""
  where
    -- 辅助函数,参数是已经积累的字符(注意是反向存储的,最后要反转)
    getLineHelper :: String -> Teletype String
    getLineHelper acc = Get (\c ->
      if c == '\n'
        then End (reverse acc)  -- 反转得到正确的字符串顺序
        else getLineHelper (c : acc)  -- 把新字符加到积累的头部(比++高效)
      )

代码解释

  1. 辅助函数getLineHelper:它接收一个String类型的参数acc,用来存储已经读取到的字符。我们选择把新字符加到acc的头部(c : acc),因为这种操作的时间复杂度是O(1),比用acc ++ [c]的O(n)更高效,最后只需要一次反转就能得到正确顺序的字符串。
  2. 终止条件:当读取到换行符'\n'时,我们用End (reverse acc)返回积累的字符串(反转后恢复正确顺序)。如果你希望返回的字符串包含换行符,只需要改成End (reverse (c : acc))即可。
  3. 递归读取:如果不是换行符,就把当前字符加入积累的字符串,继续递归调用getLineHelper读取下一个字符。

这样修改后,代码就能正确编译,并且实现了读取字符直到换行,返回完整字符串的功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:28:14