Reputation: 41
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
Upvotes: 1
Views: 568
Reputation: 27636
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 = []
Upvotes: 1
Reputation: 3497
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
Upvotes: 1