I am trying to filter by an item in a list and print them line by line. Here’s my code:
data Car = Car String [String] Int [String]
testDatabase :: [Car]
testDatabase = [Car"Casino Royale" ["Daniel Craig"] 2006 ["Garry", "Dave", "Zoe", "Kevin", "Emma"],Car"Blade Runner" ["Harrison Ford", "Rutger Hauer"] 1982 ["Dave", "Zoe", "Amy", "Bill", "Ian", "Kevin", "Emma", "Sam", "Megan"]]
formatCarRow (Car a b c d) = show a ++ " | " ++ concat [i ++ ", " | i <- init b] ++ last b ++ " | " ++ show c ++ " | " ++ concat [j ++ ", " | j <- init d] ++ last d
displayFilmsByYear :: String -> IO [()]
displayFilmsByYear chosenYear = mapM (putStrLn.formatFilmRow) [putStrLn(filter ((== chosenYear).y)) | (w x y z) <- testDatabase] -- This is the code not working i think
Why isnt this working?
If you wish to filter a list, I recommend using the
filterfunction 🙂It seems wise to explain a few things here:
Anonymous Functions:
(\car -> year car == chosenYear)is an anonymous function. It takes one argument and calls itcar. Then it determines whether that car’s year is equal to thechosenYear. I didn’t explicitly write this function’s type signature, but it’sCar -> Bool.Filtering: I gave that function to
filter, so that it would look through the list ofCars. Whenfilterfinds cars for which that function returnsTrue, it puts them in the result list. AFalseresult means that a car doesn’t make it through the filter.Function composition:
(putStrLn . showCar)This is a function that first performsshowCar, and then usesputStrLnon the result ofshowCar.Where: You’ll notice the
wherestatement at the end of my code. It should be fairly self-explanatory, you can use eitherletorwherestatements to define “local variables”. As a matter of taste, I prefer where over let.List comprenensions vs filter: List comprehensions can filter a list just like the filter function. For a function
f :: a -> Bool, and a listxs :: [a]filter f xsis the same as[x | x <- xs, f x]. As a matter of taste, I prefer spelling outfilterin such cases, since it makes it very clear that I’m filtering the list.See also LYAH # Maps and filters
—
Further recommendation: use record syntax
Instead of
Why not
(I couldn’t really tell what your last list of Strings was)
This way, you can construct a Film like this:
And you automatically have accessor functions
released :: Film -> Intname :: Film -> StringSee also LYAH # Record syntax