Неисчерпывающие паттерны в функции 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 = []
Другие вопросы по тегам