首页 > 解决方案 > 在 Haskell 中遍历字符串/文本时使用状态

问题描述

我是 Haskell 的初学者,我在解决问题时遇到了问题,如下所示:
我正在获取一个文件作为输入(文本/字符串类型,性能现在不是重要参数),我正在尝试格式化它以删除它的某些部分。
我在想我会折叠它并将文件的内容放入一个字符串/文本中,每当我到达我想要删除的部分时(因为当可放置的内容即将到来并且它有一个符号时,它会用一个符号表示当有效内容到来时),我改变了现在不应该累积的折叠的“状态”,当指示真实内容到来的符号回来时,状态应该告诉折叠继续累积。
到目前为止,我尝试过的内容如下:

checkForComment :: String -> Bool -> Bool
checkForComment "/*" _ = False
checkForComment "*/" _ = True
checkForComment "//" _ = False 
checkForComment "/n" _ = True 
checkForComment _ True = True
checkForComment _ False = False 

eraseComments :: [String] -> String
eraseComments = foldr (\emptyList listWithInput -> if checkForComment listWithInput then listWithInput ++ emptyList else []) []

当前的示例当然不起作用,因为对于我的 checkForComment 函数,我应该传递一个参数,该参数描述了以前的状态。
我希望我正确地描述了任务,不幸的是我无法解决它。如果有人可以提供帮助,我将非常高兴!:D

标签: stringhaskellinputstatefold

解决方案


最基本的选择是使用显式递归,编写一个辅助函数,该函数接受一个标志,意思是“我在评论中吗?”。例如

removeC :: String -> Bool -> String
removeC ('/':'*':rest) False = removeC rest True
removeC (x:rest)       False = x : removeC rest False
removeC ('*':'/':rest) True  = removeC rest False
removeC (_:rest)       True  = removeC rest True
removeC ""             _     = ""

然后,定义为标志提供初始状态的实际函数:

eraseComments :: String -> String
eraseComments str = removeC str False

可以将其转换为折叠,但这可能不会导致更简单、更易读的代码,因为您需要处理额外的标志。

请注意,上面的代码只是一个示例,可能并不完全适合您的任务。不过,您可能已经了解了总体思路,并且可以尝试对其进行调整以满足您的需求。


推荐阅读