开发者

Using filter on an item in a list?

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 filter function :)

data Car = Car String [String] Int [String]

year :: Car -> Int
year (Car _ _ y _) = y

filterByYear :: Int -> [Car] -> [Car]
filterByYear chosenYear cars = filter (\car -> year car == chosenYear) cars

showCar :: Car -> String
showCar car = undefined -- you can implement this how you like

displayCarsByYear :: Int -> IO ()
displayCarsByYear chosenYear = mapM_ (putStrLn . showCar) filteredCars
    where filteredCars = filterByYear chosenYear testDatabase

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 it car. Then it determines whether that car's year is equal to the chosenYear. I didn't explicitly write this function's type signature, but it's Car -> Bool.

Filtering: I gave that function to filter, so that it would look through the list of Cars. When filter finds cars for which that function returns True, it puts them in the result list. A False result means that a car doesn't make it through the filter.

Function composition: (putStrLn . showCar) This is a function that first performs showCar, and then uses putStrLn on the result of showCar.

Where: You'll notice the where statement at the end of my code. It should be fairly self-explanatory, you can use either let or where statements 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 list xs :: [a]

filter f xs is the same as [x | x <- xs, f x]. As a matter of taste, I prefer spelling out filter in 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

data Car = Car String [String] Int [String]

Why not

data Film = Film { name :: String
                 , actors :: [String]
                 , released :: Int
                 , characters :: [String]
                 }

(I couldn't really tell what your last list of Strings was)

This way, you can construct a Film like this:

lotr :: Film
lotr = Film { name = "Lord of the Rings"
            , actors = ["Elijah Wood", "Ian McKellen", "Orlando Bloom"]
            , released = 2001
            , characters = ["Frodo", "Sam", "Pippin", "Merry"]
            }

And you automatically have accessor functions

  • released :: Film -> Int
  • name :: Film -> String
  • and so forth

See also LYAH # Record syntax


The point is this:

[putStrLn(filter ((== chosenYear).y)) |  (w x y z) <- testDatabase]

You haven't understood list comprehension yet. What you want is:

[ (Car w x y z) | (Car w x y z) <- testDatabase, y==choosenYear]

Probably.

With

 mapM (putStrLn . formatCarRow) 

you have already ordered: format and then print each element of the follwoing list. Hence, the putStrLn in the list comprehension is utterly absurd.

Please note that putStrLn is in some way a misnomer: It won't print anything actually! It just constructs a thing that happens to cause printing when executed in the IO monad. It seems like this is hard to understand, but soon you will.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜