对列表中的项目使用过滤器?

Ash*_*Ash 2 haskell list filter

我试图按列表中的项目进行过滤并逐行打印.这是我的代码:

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
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?

Dan*_*ton 5

如果你想过滤一个列表,我建议使用这个filter函数:)

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
Run Code Online (Sandbox Code Playgroud)

在这里解释一些事情似乎是明智的:

匿名函数:(\car -> year car == chosenYear)是一个匿名函数.它需要一个参数并调用它car.然后它确定那辆车的年份是否等于chosenYear.我没有明确写出这个函数的类型签名,但它是Car -> Bool.

过滤:我给了该函数filter,以便它可以查看Cars 列表.当filter找到该函数返回的汽车时True,它会将它们放入结果列表中.一个False结果意味着汽车不让它通过过滤器.

函数组合:(putStrLn . showCar)这是一个首先执行的函数,showCar然后用于putStrLn结果showCar.

Where:您会注意到where我的代码末尾的陈述.它应该是相当不言自明的,您可以使用letwhere语句来定义"局部变量".作为一个品味问题,我更喜欢在哪里过度.

列出comprenensions与过滤器:列表推导可以像过滤器功能一样过滤列表.对于函数f :: a -> Bool和列表xs :: [a]

filter f xs是一样的[x | x <- xs, f x].作为一个品味问题,我更喜欢filter在这种情况下拼写,因为它很清楚我正在过滤列表.

另请参阅LYAH#Maps和过滤器

-

进一步建议:使用记录语法

代替

data Car = Car String [String] Int [String]
Run Code Online (Sandbox Code Playgroud)

为什么不

data Film = Film { name :: String
                 , actors :: [String]
                 , released :: Int
                 , characters :: [String]
                 }
Run Code Online (Sandbox Code Playgroud)

(我真的不知道你的最后一个字符串列表是什么)

这样,你可以构建一个像这样的电影:

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

并且您自动拥有访问者功能

  • released :: Film -> Int
  • name :: Film -> String
  • 等等

另请参阅LYAH #Record语法