Haskell 如何计算有序[Char]中出现的Char?
我有一个输入[String],如下所示:Haskell 如何计算有序[Char]中出现的Char?,haskell,recursion,functional-programming,conditional-statements,immutability,Haskell,Recursion,Functional Programming,Conditional Statements,Immutability,我有一个输入[String],如下所示: main = do let res = calcCounts ["IOIOOIOOI\r","OOIIIOOO\r",...] 我希望使用非统一的基本系统按顺序计算I和O实例 我创建了一个类型: 到目前为止,我创建的代码每次都尝试单步执行输入并创建一个新的OutputState,同时在达到每个[Char]为“\r”的已完成条件和[String]的列表末尾但不完整的条件之前考虑以前的OutputState: calcCounts :: [String
main = do
let res = calcCounts ["IOIOOIOOI\r","OOIIIOOO\r",...]
我希望使用非统一的基本系统按顺序计算I和O实例
我创建了一个类型:
到目前为止,我创建的代码每次都尝试单步执行输入并创建一个新的OutputState,同时在达到每个[Char]为“\r”的已完成条件和[String]的列表末尾但不完整的条件之前考虑以前的OutputState:
calcCounts :: [String] -> [OutputState]
calcCounts input = map genOutputState input
genOutputState :: [Char] -> OutputState
genOutputState (x:xs)
| x == '\r' = --return final OutputState
| otherwise do
let currOutputState = incrementOutputState x
genOutputState xs --also pass current OutputState back each recursion
incrementOutputState :: OutputState -> Char -> OutputState
incrementOutputState pos@prevOS x = do
| if x == 'I' = do
let currOutputState = OutputState pos{totNumA} pos{totNumB} pos{numA}+1 pos{numB}
| if currOutputState{numA} == 4 = OutputState currOutputState{totNumA}+1 currOutputState{totNumB} 0 0
| otherwise = do
let currentOutputState = OutputState pos{totNumA} pos{totNumB} pos{numA} pos{numB}+1
| if currentOutputState{numB} == 4 = OutputState currOutputState{totNumA} currOutputState{totNumB}+1 0 0
最终输出应为[OutputState,OutputState,…]
我知道我的代码目前不合法,并且缺少逻辑。对此表示歉意。我仍然在返回Haskell和函数式编程的过程中。在命令式范例中,我会使用可变变量来跟踪必要的计数,但我明白这不是从函数意义上思考问题的正确方式
非常感谢您的帮助 我想这正是你想要做的,尽管我仍然不能完全确定我是否理解正确 数据输出状态=输出状态{totNumI::Int, totNumO::Int, numI::Int, numO::Int }衍生节目 genOutputState::String->OutputState genOutputState=foldl递增输出状态输出状态0 递增输出状态::输出状态->字符->输出状态 将OutputState输出状态ti增加到3否“I”=输出状态ti+1到0 incrementOutputState输出状态ti到ni否'I'=输出状态ti到ni+1否 incrementOutputState输出状态ti到ni 3'O'=输出状态ti到+1 0 incrementOutputState输出状态ti到ni no'O'=输出状态ti到ni no+1 incrementOutputState os u=os-除了“I”和“O”之外,不要为字符增加任何内容
我建议您多学习一些Haskell教程,因为我觉得您还不太了解语法和功能性思维方式。我不太明白您到底想做什么。你能详细说明托特努马和努马的区别吗?基因输出状态ioi\r的结果应该是什么?pos{totNumA}pos{totNumB}pos{numA}+1 pos{numB}无效。你只需简单的模式匹配就可以了pos@OutputState{totNumA=a,totNumB}然后在表达式中写入pos{totNumA=a+1}。很抱歉@RikVanToor,所需的输出将是[OutputState,OutputState,…],在该示例中,内容将是{totNumI=1,totNumO=1,numI=0,num0}。我已经将OutputState从As和Bs更改为Is和Os以使其更有意义。感谢@WillemVanOnsem,我确实理解你的意思,但我的语法很弱。我在使用OutputState时遇到很多问题。例如,它当前没有从genOutputState传递到incrementOutputState,因为递归会导致let currOutputState=incrementOutputState OutputState 0 x为[Char]中的每个Char重置OutputState。不清楚要执行什么操作。我认为在一个列表中只计算相等的元素。只需使用Data.Map作为累加器折叠列表,并使用insertwith+作为函数就可以了。我没有非统一的基础。我有一个后续问题,希望你不介意回答。用于“传递”提供给genOutputState的字符串的功能是什么?它是否像函数声明中未引用的事实一样简单,即genOutputState str=。。?谢谢你的帮助。@macourtney7,这就是所谓的eta降低。Eta减少意味着\x->fx与f是一样的。在这种情况下,这意味着getOutputState str=foldl incrementOutputState OutputState 0 0 0 str也可以写为getOutputState=foldl incrementOutputState OutputState 0 0 0 0
calcCounts :: [String] -> [OutputState]
calcCounts input = map genOutputState input
genOutputState :: [Char] -> OutputState
genOutputState (x:xs)
| x == '\r' = --return final OutputState
| otherwise do
let currOutputState = incrementOutputState x
genOutputState xs --also pass current OutputState back each recursion
incrementOutputState :: OutputState -> Char -> OutputState
incrementOutputState pos@prevOS x = do
| if x == 'I' = do
let currOutputState = OutputState pos{totNumA} pos{totNumB} pos{numA}+1 pos{numB}
| if currOutputState{numA} == 4 = OutputState currOutputState{totNumA}+1 currOutputState{totNumB} 0 0
| otherwise = do
let currentOutputState = OutputState pos{totNumA} pos{totNumB} pos{numA} pos{numB}+1
| if currentOutputState{numB} == 4 = OutputState currOutputState{totNumA} currOutputState{totNumB}+1 0 0