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

Haskell中如何将字符串转换为LineItem类型的列表?

解决方案

要实现累积普通字符为单个Word的逻辑,你需要借助辅助递归函数来携带当前累积的字符。核心思路是:用辅助函数跟踪正在构建的单词字符,直到遇到空格/换行时,将累积的字符打包成Word,再继续处理剩余字符串。

修正后的完整代码

-- 1.1
data LineItem = Space | Newline | Word String
    deriving (Eq)

-- 1.2
mkSpace :: LineItem
mkSpace = Space

mkNewline :: LineItem
mkNewline = Newline

mkWord :: String -> LineItem
mkWord = Word 

-- 1.3 修正原有的lineItemToStr(原实现会输出带引号的字符串,不符合预期)
lineItemToStr :: LineItem -> String
lineItemToStr Space = " "
lineItemToStr Newline = "\n"
lineItemToStr (Word s) = s

instance Show LineItem where
    show = lineItemToStr

-- 主函数:调用辅助函数,初始累积字符为空
toLineItems :: String -> [LineItem]
toLineItems = toLineItemsHelper ""

-- 辅助函数:参数1=当前累积的单词字符,参数2=剩余未处理的字符串
toLineItemsHelper :: String -> String -> [LineItem]
-- 情况1:遇到空格
toLineItemsHelper acc (' ':rest) = 
    case acc of
        "" -> Space : toLineItemsHelper "" rest  -- 无累积字符,直接加Space
        _  -> Word acc : Space : toLineItemsHelper "" rest  -- 先把累积的转成Word,再加Space
-- 情况2:遇到换行
toLineItemsHelper acc ('\n':rest) =
    case acc of
        "" -> Newline : toLineItemsHelper "" rest
        _  -> Word acc : Newline : toLineItemsHelper "" rest
-- 情况3:遇到普通字符,加入累积列表
toLineItemsHelper acc (c:rest) = toLineItemsHelper (acc ++ [c]) rest
-- 情况4:字符串处理完毕,若有累积字符则转成Word
toLineItemsHelper acc "" = if null acc then [] else [Word acc]

逻辑解释

  1. 辅助函数的作用:toLineItemsHelper的第一个参数acc用来临时存储正在构建的单词字符,避免每次递归只处理单个字符。
  2. 空格/换行的处理:遇到分隔符时,先检查是否有累积的字符——如果有,先将其转为Word,再添加分隔符对应的LineItem;如果没有,直接添加分隔符。
  3. 普通字符的处理:将当前字符追加到累积字符串acc中,继续递归处理剩余部分。
  4. 收尾处理:当字符串处理完时,若acc不为空,说明最后还有一个未完成的单词,需要将其转为Word加入结果列表。

测试示例

比如输入字符串"hello world\nfoo",调用toLineItems会得到:

[Word "hello", Space, Word "world", Newline, Word "foo"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 12:40:17