I am trying to implement a function that checks that all items of a list are equal to a given value. The function should take a list of strings, returning True
if every string is exactly "car"
, and False
otherwise.
*Main> go ["car","car","car"]
True
*Main> go ["car","car","bus"]
False
This is my current implementation but it does not seem to work correctly.
go :: [String] -> Bool
go ("car":[]) = True
go ("car":xs) = False
go _ = False
CodePudding user response:
The line go ("car":xs) = False
means that a list that contains as first item "car"
and has at least one extra item (since the pattern before covers the case of a singleton list) should return False
. You should recurse on the list, so the function should look like:
go :: [String] -> Bool
go ("car" : xs) = …
go (_ : _) = False
go [] = True
where you still need to fill in the …
part, this should make a recursive function call.
You can however implement go
with all:: Foldable t => (a -> Bool) -> t a -> Bool
:
go :: Foldable f => f String -> Bool
go = all ("car" ==)
CodePudding user response:
These are what you get from your code:
with
go ("car":[]) = True
, you getgo ["car"] -> True
with
go ("car":xs) = False
("car":xs)
is a pattern matching that captures a list of the form ["car",...]
, so you will get
go ["car"] -> False -- not used because the first case takes priority
go ["car", "car"] -> False -- INCORRECT
go ["car", "bus"] -> False
go ["car", ...] -> False -- NOT ALWAYS CORRECT
- with
go _ = False
_
is a pattern matching that captures any list, so you will get
go [] -> False
go ["car"] -> False -- not used because the first case takes priority
go ["bus"] -> False
go ["car", ...] -> False -- not used because the second case takes priority
go [...] -> False
You can get a correct answer with
go [] = True
go ("car":xs) = ...
go _ = False
but you need to fill ... with something that depends on xs (the tail of the list).
The head (first element) of ("car":xs)
is already equal to "car"
.