Haskell - 用模式解码消息

Haskell - Decode message with pattern

我是 Haskell 的新手,目前正在学校学习。我有一项学校任务,我必须对包含特定模式的消息进行解码,但我不知道该怎么做。

模式看起来像这样:如果一个字母有一个辅音,后面跟着字符 'o',然后再次后面跟着与之前相同的辅音,它应该替换那个子串("XoX",其中X是辅音)只有辅音。例如,如果我解码字符串 "hohejoj",它应该 return "hej"。对不起,如果我解释得不好,但我想你明白了。

这是我目前的代码(但它不起作用):¨

karpsravor :: String->String
karpsravor s = karpsravor_help s ""
    where karpsravor_help s res
           |s == "" && (last res) == 'o' = (init res)
           |s==""=res
           |otherwise = karpsravor_help (drop 3 s) (res ++ (consDecode (take 3 s)))

consDecode :: String->String
consDecode a
    |(length a) < 3 = ""
    |a == [(head a)]++"o"++[(head a)] = [(head a)]
    |otherwise = a

代码完全损坏且写得不好(愚蠢的方法)但我不知道如何解决这个问题。请帮忙!

Pattern match 查找出现的 'o'。即,使用

karpsravorhelp (a:'o':b:rest) res = ...

你不能在上面有a:'o':a:rest,你不能模式匹配相等;你需要使用守卫来确保 a == b:

karpsravorhelp (a:'o':b:rest) res | a == b = ... | otherwise = ...

你还必须确保 ab 是辅音,这只是第一个守卫的 'and' 条件。对于 otherwise 条件,确保递归调用调用 (b:rest) 因为你可能有类似 a:'o':b:'o':b:....

的东西

还要确保匹配其他两种模式:

  1. 空列表,[]
  2. x:rest,必须遵循上述模式;这样,它将首先尝试匹配 a:'o':b:rest 模式,如果不存在,则取下一个字母。

一种方法是使用 Data.List 中的 unfoldr。您可以使用 case 表达式对 a : 'o' : b : rest 进行模式匹配,然后使用保护 | 检查 ab 是否相等而不是元音。然后只包括模式不匹配时的基本情况。

notVowel :: Char -> Bool
notVowel = (`notElem` "aeiouAEIOU")

karpsravor :: String -> String
karpsravor = unfoldr $ \str -> case str of
    a : 'o' : b : rest
        | a == b && notVowel a -> Just (a, rest)
    a : rest                   -> Just (a, rest)
    ""                         -> Nothing