Неисчерпывающие паттерны в функции haskell
Я думаю, что мне не хватает случая, когда есть список из одного элемента, но я не могу найти способ написать его, может кто-нибудь мне помочь?
getBoard :: [String] -> [String]
getBoard (h:t) | isLOL h = h: getBoard (t)
| otherwise = []
isLOL :: String -> Bool
isLOL [ ] = True
isLOL (h:t) | h>='a' && h<='z' || h >='A' && h<='Z' = isLOL t
| otherwise = False
2 ответа
getBoard [] = []
это линия, которую вы хотите. Как это:
getBoard :: [String] -> [String]
getBoard [] = []
getBoard (h:t) | isLOL h = h: getBoard (t)
| otherwise = []
isLOL :: String -> Bool
isLOL [] = True
isLOL (h:t) | h>='a' && h<='z' || h >='A' && h<='Z' = isLOL t
| otherwise = False
Прежде всего, в вашем определении getBoard
проблема в том, что охранники (вещи после |
) проверяются после шаблона (h:t
в вашем случае) подобраны. Так что, если аргумент getBoard
не совпадает h:t
(то есть []
), затем две ветви (включая otherwise
филиал) не проверены. Решением этой проблемы является добавление совпадения на []
:
getBoard (h:t) | isLOL h = h : getBoard t
| otherwise = []
getBoard [] = []
Тем не менее, матчи с неудачными охранниками проваливаются, так что вы можете написать это как
getBoard (h:t) | isLOL h = h : getBoard t
getBoard _ = []
Теперь о том, как лучше написать эту функцию, используя схемы рекурсии из Prelude:
isLOL
может быть переписан как
isLOL = all $ \h -> 'a' <= h && h <= 'z' || 'A' <= h && h<= 'Z'
а также getBoard
можно переписать аналогичным образом, отметив, что он всегда будет возвращать исходный список, если каждый символ isLOL
и пустой список в противном случае:
getBoard cs | all isLOL cs = cs
| otherwise = []