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

如何实现Haskell递归函数readUntil:读取用户输入至满足条件

完善Haskell的readUntil递归实现

我来帮你搞定这个递归版的readUntil函数~先看看你原代码里的小问题,再给出两种可行的实现方案:

首先,你的核心思路是对的——用辅助递归函数累积输入行,直到触发停止条件。不过原代码里有个明显的语法错误:if f = True这部分不对,因为f是String -> Bool类型的函数,你需要把当前读取的行x传进去,写成if f x才行。

高效版实现(推荐)

这个版本用:把新行加到列表头部,最后反转得到正确的输入顺序,效率更高(因为:是O(1)操作,最后一次reverse是O(n),整体复杂度更优):

readUntil :: (String -> Bool) -> IO [String]
readUntil f = go []
  where
    go accumulated = do
      currentLine <- getLine
      if f currentLine
        then return (reverse accumulated)  -- 反转后返回正确顺序的已读行
        else go (currentLine : accumulated)  -- 把当前行加入累积列表,继续递归

直观版实现(适合理解)

如果觉得反转的逻辑有点绕,也可以每次把新行追加到列表尾部,虽然效率稍低(++是O(n)操作),但递归流程更直观:

readUntil :: (String -> Bool) -> IO [String]
readUntil f = go []
  where
    go accumulated = do
      currentLine <- getLine
      if f currentLine
        then return accumulated  -- 直接返回已累积的行
        else go (accumulated ++ [currentLine])  -- 追加当前行后继续递归

逻辑说明

不管哪种版本,核心的递归逻辑都是一致的:

  • 辅助函数go负责累积已经读取的行,参数accumulated就是当前的累积列表
  • 每次调用getLine读取用户输入的一行
  • 用判定函数f检查当前行:如果返回True,就停止递归,返回累积的行列表;否则把当前行加入累积列表,继续递归调用go

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:37:03