用户定义类型的递归调用的表示法

Joh*_*ohn 1 recursion haskell types notation

可能重复:
迭代字符串并用haskell中的子字符串替换单个字符

我试图实现,着眼于一个字符串([个字符]),并检查每一个字母,这是否应该信另一个字符串替换功能.例如,我们可能有一个由"XYF"组成的[Chars]和说"X = HYHY","Y = OO"的规则,那么我们的输出应该变成"HYHYOOF".

我想使用我定义的以下两种类型:

type Letters = [Char]
data Rule = Rule Char Letters deriving Show
Run Code Online (Sandbox Code Playgroud)

我的想法是,使用警卫,该功能应该类似于下面的内容.然而问题是,当我想浏览所有规则以查看它们中的任何一个是否适合当前字母x时,我找不到关于如何递归调用的任何信息.我希望任何人都可以给出一些关于符号如何发展的提示.

apply :: Letters -> [Rule] -> Letters
apply _ _ = []
apply (x:xs) (Rule t r:rs)  
| x /= t = apply x (Rule t rs)
| x == t = r++rs:x
| otherwise  = 
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 5

我会建议一个辅助函数来检查规则是否匹配,

matches :: Char -> Rule -> Bool
matches c (Rule x _) = c == x
Run Code Online (Sandbox Code Playgroud)

然后检查每个字符是否有任何匹配规则

apply :: Letters -> [Rule] -> Letters
apply [] _ = []
apply s [] = s
apply (c:cs) rules = case filter (matches c) rules of
                       [] -> c : apply cs rules
                       (Rule _ rs : _) -> rs ++ apply cs rules
Run Code Online (Sandbox Code Playgroud)

如果你在rules内部尝试显式递归apply,它将变得太丑陋,因为你需要记住完整的规则列表来替换后面的字符.

  • 问题是您有两个要遍历的列表,字母列表和规则.在同一个函数中执行此操作并不好,因为您需要恢复下一个字母的完整规则集,您需要三个参数.分离两个遍历可以缩短,更易于理解和维护代码. (5认同)