Это действительно правильно. Первая проблема состоит в том, что ваше последнее предложение определяет функцию concatBackslash
, тогда как другие предложения определяют функцию concat<b>On</b>Backslash
(с On
). Таким образом, это означает, что Haskell считает эти две разные функции. Вы можете переименовать их в:
concatOnBackslash :: [String] -> [String]
concatOnBackslash [] = []
concatOnBackslash [x] = [x]
concatOnBackslash [x, xs] = case last x of
'\\' -> [(init x) ++ " " ++ xs]
_ -> [x, xs]
<b>concatOnBackslash</b> (x : xx : xs) = case last x of
'\\' -> concatOnBackslash (((init x) ++ " " ++ xx) : xs)
_ -> x: concatOnBackslash (xx : xs)
Теперь контрольный пример будет работать, но функция все еще не очень безопасна.
Функции last :: [a] -> a
(и init :: [a] -> [a]
) являются неполными . Для пустого списка это не так:
Prelude> last []
*** Exception: Prelude.last: empty list
Prelude> init []
*** Exception: Prelude.init: empty list
Это значит, что concatOnBackslash
будет ошибкой, если первый элемент пуст, как:
Prelude Data.List.Split> concatOnBackslash ["", "a"]
*** Exception: Prelude.last: empty list
Таким образом, здесь лучше использовать сопоставление с образцом, например:
concatOnBackslash :: [String] -> [String]
concatOnBackslash [] = []
concatOnBackslash [x] = [x]
concatOnBackslash [<b>[]</b>, xs] = ...
concatOnBackslash [x<b>@(_:_)</b>, xs] = case last x of
'\\' -> [(init x) ++ " " ++ xs]
_ -> [x, xs]
concatOnBackslash (<b>[]</b> : xx : xs) = ...
concatOnBackslash (x<b>@(_:_)</b> : xx : xs) = case last x of
'\\' -> concatOnBackslash (((init x) ++ " " ++ xx) : xs)
_ -> x: concatOnBackslash (xx : xs)