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

Haskell使用foldl实现字符替换为剩余长度的匿名函数问题

实现要求

你需要借助foldl编写符合如下签名的Haskell函数:

  • 入参为字符串str,返回值为一个匿名函数
  • 返回的匿名函数接收单个字符参数c,将原字符串str中所有与c相等的字符,替换为该字符所在位置之后剩余字符的数量(转成字符串形式)

函数签名:

speak :: String -> (Char -> String)

运行示例:

  • speak "Hello" 'e' 输出 "H3llo":字符'e'位于索引1位(从0开始计数),后方剩余3个字符,因此替换为"3"
  • speak "gate" 't' 输出 "ga1e":字符't'位于索引2位,后方剩余1个字符,因此替换为"1"
原代码错误点

你提交的错误代码如下:

speak :: String -> (Char ->String)
speak str = foldl (\x -> if x == str then x = show(length str) else str) str 

存在4个核心问题:

  • 返回值不符合签名要求:直接返回了foldl的计算结果,没有定义接收字符c的匿名函数
  • foldl入参不符合语法:foldl要求接收的折叠函数带2个参数(累加器、当前遍历元素),你写的lambda仅接收1个参数
  • 语法非法:Haskell是纯函数式语言,不存在命令式赋值操作x = ...
  • 逻辑完全缺失:没有逐字符遍历判断匹配,也没有记录每个位置对应的后方剩余字符数,替换逻辑不成立
基于foldl的正确实现

实现思路:遍历字符串时用二元组作为累加器,同时维护「已构建的结果字符串」和「当前位置后方的剩余字符数」两个状态,每遍历一个字符就更新状态,遍历完成后取累加器中的结果字符串即可。

speak :: String -> (Char -> String)
speak str = \c -> fst $ foldl processChar ("", length str - 1) str
  where
    processChar (acc, remainLen) currChar
      | currChar == c = (acc ++ show remainLen, remainLen - 1)
      | otherwise = (acc ++ [currChar], remainLen - 1)

代码逻辑说明:

  • speak str直接返回接收字符c的匿名函数,匹配函数签名要求
  • 折叠初始值:初始结果为空串,第一个遍历字符(索引0)后方的剩余字符数为length str - 1
  • 每一步遍历的处理规则:
    • 如果当前字符和待替换字符c相等,就把当前剩余长度转成字符串追加到结果末尾
    • 如果不相等,就把原字符直接追加到结果末尾
    • 无论是否匹配,下一步的剩余长度减1
  • 折叠完成后取累加器二元组的第一个元素,就是最终替换完成的字符串
    该实现可以直接通过给出的两个示例测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:06:29