As requested, here’s a version with and without the use of where. I think this is a good demonstration of why the advice not to use where is bad advice. I think the first version is a lot easier to understand.
Keep in mind, functional programming isn’t a monastic vow to forswear certain keywords out of masochism. Nor is it a checklist of fashion tips (where is so last season!). “You should avoid that construct arbitrarily because it’s not the ‘functional’ thing to do” really is not how it works. So you shouldn’t uglify your code for the sake of a tip like that.
It is often a good idea to follow the same coding style as other programmers so they will find it easier to understand you. (For example, Adam Smith was subtly trying to train you that acc is a common name for an accumulator and go a common name for a recursive helper function, and they help other programmers figure out the pattern he’s using.) But in fact Haskell programmers do use where, a lot.
Anyway, the code:
longeststrings :: [String] -> [String]
{- Filters all strings as long as any other in the list. -}
longeststrings = foldr go []
where
go x [] = [x]
go x leaders | newlength > record = [x]
| newlength == record = x:leaders
| otherwise = leaders
where
record = (length . head) leaders
newlength = length x
longestStringsUsingLambda :: [String] -> [String]
longestStringsUsingLambda = foldr
(\x leaders ->
if leaders == [] then [x]
else case compare (length x) (length $ head leaders) of
GT -> [x]
EQ -> x:leaders
LT -> leaders )
[]
main :: IO ()
main = let testcases = [ ["meow","cats","dog","woof"],
["foo","bar","baz"],
["meep","foo","bar","baz","fritz","frotz"]
]
in foldMap print $
map longestStringsUsingLambda testcases
You can try eliminating the let testcases = ... and see if you consider that an improvement.