优化Haskell函数以正确应用规则并避免重复字符

mwngjboj  于 2024-01-08  发布在  其他
关注(0)|答案(3)|浏览(122)

我有一个任务,要求我们实现一些功能。
我们必须实现一个函数apply :: State -> [Rule] -> State,其中State是String,Ruledata Rule = Rule Char State deriving Show
这意味着我们应该能够调用函数s.t. apply "FXRYF" [Rule 'X' "XRYF", Rule 'Y' "FXLY"]将产生FXRYFRFXLYF"
我有一个(不充分的)解决方案,那就是缺少一些我不知道如何做的东西。

type State = String
data Rule = Rule Char State deriving Show 

apply :: State -> [Rule] -> State
apply state rules = concat [if char == c then s else [char] | char <- state, Rule c s <- rules]

字符串
将产生FFXRYFXRRYFXLYFF
问题是它对rules中的每一条规则都应用else [char]。理想情况下,它应该只对rules中的最后一条规则应用else [char]
该怎么办呢?

7xllpg7q

7xllpg7q1#

我想出来了,这就是解决方案:

apply state rules = 
    let ruleTable = [(c, s) | Rule c s <- rules]
    in concat [maybe [char] id (lookup char ruleTable) | char <- state]

字符串
因此,如果lookup函数返回Nothing,那么我们将[char]连接起来,否则我们将返回对应于ruleTable中某个cs

iovurdzv

iovurdzv2#

根据@DavidFletcher在其中一条评论中的建议,并假设只有第一条规则匹配重要:

apply :: State -> [Rule] -> State
apply state rules = concatMap applyRulesToChar state  where
    applyRulesToChar char = let  ss = [s | Rule c s <- rules, c==char]
                            in   if (null ss) then [char] else (head ss)

字符串

ru9i0ody

ru9i0ody3#

我建议拆分出一个辅助函数,将所有规则应用于单个字符。

applyRulesOnce :: [Rule] -> Char -> [Char]
applyRulesOnce rules char = case [s | Rule c s <- rules, c == char] of
    [] -> [c]
    s:_ -> s

applyRules :: [Rule] -> State -> State
applyRules = concatMap . applyRulesOnce

字符串

相关问题