Non-exhaustive patterns in function haskell

578 Views Asked by At

I think I am missing the case where there's a one element list but I can't find a way to write it can someone help me?

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

There are 2 best solutions below

0
On BEST ANSWER
getBoard [] = []

is the line you want. Like this:

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
0
On

First of all, in your definition of getBoard, the problem is that the guards (the stuff after the |) are checked after the pattern (h:t in your case) are matched. So if the argument to getBoard doesn't match h:t (i.e. is []), then the two branches (including the otherwise branch) are not checked. The solution to this is to add a match on []:

getBoard (h:t) | isLOL h = h : getBoard t
               | otherwise = []
getBoard [] = []

However, matches with failing guards fall through, so you can write that as

getBoard (h:t) | isLOL h = h : getBoard t
getBoard _               = []

Now, as for how to write this function in a better way, using recursion schemes from the Prelude:

isLOL can be rewritten as

isLOL = all $ \h -> 'a' <= h && h <= 'z' || 'A' <= h && h<= 'Z'

and getBoard can be rewritten similarly, noting that it will always return the original list if every character isLOL, and the empty list otherwise:

getBoard cs | all isLOL cs = cs
            | otherwise = []