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

如何利用Haskell State Monad生成替换后的目标整数列表?

解决Haskell State Monad同时生成转换列表和计数的问题

你的代码目前只返回了计数结果,核心问题在于终止条件返回的是计数而非处理后的元素列表,且递归时没有将当前元素的转换结果与后续列表拼接。下面是修改后的完整方案:

修正后的代码

module Main( main ) where
import Control.Monad.State

l = [ Right 6, Left "AAA", Right 3, Right 8, Left "CCC", Right 2, Right 9, Right 1, Left "D"]

scanList :: [ Either String Int ] -> State (Int,Int) [ Int ]
scanList [] = return []  -- 遍历结束时返回空列表,计数保留在State中
scanList (x:xs) = do
    (ns, ni) <- get
    -- 一次匹配x,同时获取新状态和当前元素的转换值
    let (newState, currentVal) = case x of
            Left _ -> ((ns + 1, ni), 0)  -- Left类型:字符串计数+1,转换为0
            Right i -> ((ns, ni + 1), i) -- Right类型:整数计数+1,保留原值
    put newState  -- 更新状态
    rest <- scanList xs  -- 递归处理剩余元素
    return (currentVal : rest)  -- 拼接当前值和后续结果

startState = (0,0)

main = do
    -- 使用runState同时获取处理后的列表和最终计数状态
    let (processedList, (strCount, intCount)) = runState (scanList l) startState
    putStrLn $ "目标列表: " ++ show processedList
    putStrLn $ "统计结果: 字符串数量=" ++ show strCount ++ ", 整数数量=" ++ show intCount

关键改动说明

  1. 终止条件调整:原代码终止时返回[ns,ni](计数列表),现在改为返回空列表[],因为遍历完成后没有更多元素需要加入结果,计数会保存在State的最终状态中。
  2. 递归逻辑修正:
    • 不再重复匹配x,而是一次匹配同时得到新的状态和当前元素的转换值,更简洁高效。
    • 递归处理剩余元素后,将当前转换值与递归结果拼接(currentVal : rest),确保所有元素都被加入结果列表。
  3. 结果获取方式:使用runState替代evalState,这样可以同时拿到处理后的列表和最终的计数状态(字符串数、整数数)。

运行这段代码后,你会得到:

目标列表: [6,0,3,8,0,2,9,1,0]
统计结果: 字符串数量=3, 整数数量=6

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:27:27