Home > Enterprise >  Haskell check in list
Haskell check in list

Time:11-02

I have a string which has several words in it, and I have to check if the first character is the same as the previous word last character. I've been told to use the the words built in function.

Here is what I've done:

validGame1 :: [String] -> Bool
validGame1 [] = True
validGame1 [x] = True
validGame1 (a:b:xs)
    |last a == head b = validGame1 (b:xs)
    |otherwise = False

but i'm getting exceptions when the input should be True

example : validGame "bread door room mad" (this should be True but it throws an exception) validGame "bread car room mad" (this should be False and it works well)

CodePudding user response:

It seems like you are forgetting to use words. This works for me:

ghci> validGame1 (words "bread door room mad")
True
ghci> validGame1 (words "bread car room mad")
False

If you want to encapsulate that into one function you can write:

validGame1 :: String -> Bool
validGame1 inp = go (words inp) where
  go [] = True
  go [x] = True
  go (a:b:xs)
    | last a == head b = go (b:xs)
    | otherwise = False

CodePudding user response:

As an addendum, it's possible to solve this problem without ever using words simply with recursion and pattern matching.

check :: [Char] -> Bool
check "" = True
check [_, _] = True
check (a:tl@(' ':b:c))
  | a == b = check tl
  | otherwise = False
check (_:tl) = check tl

We can consider any one or two character string to meet the specifications laid out.

For three or more characters, if the middle character is a space, if the two characters on either side are the same, we can check the tail of the string. Otherwise we know the string does not pass the check and return False.

If the string is three or more characters, but the middle character is not a space, continue checking the tail of the string.

Note: this does not handle a string where words are separate by multiple spaces.

If we want to handle that scenario, we can add a few patterns to our function.

check :: [Char] -> Bool
check "" = True
check [_, _] = True
check (' ':tl@(' ':b:_)) = check tl
check (a:tl@(' ':' ':_)) = check $ a:' ':(dropWhile (== ' ') tl)
check (a:tl@(' ':b:_))
  | a == b = check tl
  | otherwise = False
check (_:tl) = check tl
  • Related