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

Haskell自定义sep函数(类splitOneOf)实现及类型错误排查

搞定Haskell sep函数的类型匹配问题

嘿,我看到你备考期末时写这个类似splitOneOf的sep函数遇到了类型错误,咱们一起来把它解决掉!

需求回顾

你要实现的sep函数需要:

  • 接收两个参数:分隔符列表和目标列表
  • 检测并移除目标列表中的分隔符字符
  • 返回分割后的元素列表的列表
  • 示例:输入sep " \t\n" "As armas\te\tos barões\n que",应返回["As","armas","e","os","barões","que"]

你的当前代码与错误分析

你写的代码是这样的:

sep :: Eq a => [a] -> [a] -> [[a]]
sep _ [] = []
sep n (x:xs) | x `elem` n = " " ++ sep n xs | otherwise = x : sep n xs

报错的核心是类型不匹配:

  1. 分隔符分支的" " ++ sep n xs:" "是[Char]类型,而sep n xs的返回值是[[a]](列表的列表),这俩根本没法用++拼接
  2. 非分隔符分支的x : sep n xs:x是单个元素(类型a),但sep n xs是[[a]],:运算符要求左右两边类型统一(左边是元素,右边是同类型元素的列表),这里显然不匹配

正确的实现思路与代码

我们需要用一个辅助函数来维护当前正在构建的单词,遍历目标列表时逐步攒单词,遇到分隔符时把攒好的单词加入结果(如果有的话),最后处理末尾剩余的单词。

正确的代码如下:

sep :: Eq a => [a] -> [a] -> [[a]]
sep delimiters = go []
  where
    -- 遍历到末尾时,若还有未完成的单词就返回,否则返回空列表
    go current [] = if null current then [] else [current]
    go current (x:xs)
      -- 遇到分隔符的情况
      | x `elem` delimiters = 
          if null current 
            then go [] xs  -- 没有正在构建的单词,直接跳过分隔符
            else current : go [] xs  -- 把当前单词加入结果,重置当前单词继续遍历
      -- 遇到非分隔符的情况,把字符加入当前正在构建的单词
      | otherwise = go (current ++ [x]) xs

代码解释

  • 辅助函数go的第一个参数current用来存储当前正在拼接的单词(初始为空列表)
  • 当遍历到目标列表末尾时,如果current不为空,就把它作为最后一个元素返回,避免丢失最后一个单词
  • 遇到分隔符时:如果当前没有正在构建的单词(比如连续多个分隔符),就直接跳过;如果有,就把这个单词加入结果列表,然后重置current继续处理剩下的内容
  • 遇到非分隔符字符时,把它追加到current里,继续构建当前单词

测试一下你的示例输入:

sep " \t\n" "As armas\te\tos barões\n que"
-- 输出:["As","armas","e","os","barões","que"]

完全符合你的需求!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:42:21