Haskell中不修改签名实现RegModule Monad扫描字符并返回字符串
解决方案
你的核心问题是错误地试图从状态d中获取已扫描字符,但d是通用状态类型,不一定存储扫描过的内容,而且已扫描字符实际来自输入字符串,需要通过RegModule的底层运行逻辑直接提取。
正确实现collect函数
不需要依赖fetchData,直接操作RegModule的底层函数,在运行时截取输入字符串中被扫描的片段:
collect :: RegModule d a -> RegModule d (String, a) collect module = RegModule $ \s i d -> do (a, j, d') <- runRegModule module s i d let scannedStr = take j (drop i s) return ((scannedStr, a), j, d')
实现说明
- 调用传入的
module运行后,会得到结果a、索引偏移量j(即扫描了j个字符)、新状态d' - 从输入字符串
s中,截取从起始索引i开始的j个字符,就是本次扫描到的内容 - 返回的结果保持原
module的索引偏移j和状态d',同时把扫描到的字符串和原结果a组成元组返回
这样既满足了不修改类型签名的要求,又正确实现了需求:保持原扫描行为的同时,返回已扫描的字符组成的字符串。
测试验证
比如用scanChar测试:
testCollect = runRegModule (collect scanChar) "abc" 0 () -- 结果为 [("a", 'a'), 1, ()]
完全符合预期:扫描第一个字符'a',索引从0变为1,同时返回已扫描的字符串"a"。
内容的提问来源于stack exchange,提问作者Piskator
相关产品推荐
相关产品推荐

