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)
为什么这不起作用?
如果你想过滤一个列表,我建议使用这个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我的代码末尾的陈述.它应该是相当不言自明的,您可以使用let或where语句来定义"局部变量".作为一个品味问题,我更喜欢在哪里过度.
列出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 -> Intname :: Film -> String另请参阅LYAH #Record语法