0

我无法从这个给定的数据库中输出某些信息:

type Title = String
type Actor = String
type Cast = [Actor]
type Year = Int
type Fan = String
type Fans = [Fan]
type Period = (Year, Year)
type Film = (Title, Cast, Year, Fans)
type Database = [Film]

testDatabase :: Database
testDatabase = [("Casino Royale", ["Daniel Craig", "Eva Green", "Judi Dench"], 2011, ["Garry", "Dave", "Zoe", "Kevin", "Emma"]),
    ("Cowboys & Aliens", ["Harrison Ford", "Daniel Craig", "Olivia Wilde"], 2011, ["Bill", "Jo", "Garry", "Kevin", "Olga", "Liz"]),     
        ("Catch Me If You Can", ["Leonardo DiCaprio", "Tom Hanks"], 2006, ["Zoe", "Heidi", "Jo", "Emma", "Liz", "Sam", "Olga", "Kevin", "Tim"])]

注意:由于列表的大小,这只是数据库的一部分。

我正在尝试编写一个函数,该函数允许用户输入年份并仅输出电影标题。我对粉丝进行了类似的操作,用户输入粉丝名称并输出他们喜欢的电影。 ..对此的代码如下所示:

filmsByFan y = map (\(a,_,_,_) -> a) $ filter (\(_,_,_,a) -> elem y a) testDatabase

这 100% 有效,所以我用 byYear 尝试了一个类似的方法:

filmsByYear y = map (\(a,_,_,_) -> a) $ filter (\(_,_,a,_) -> elem y a) testDatabase

但这不会编译...这是因为类型 Year 设置为 Int 吗?如果是这样,是否可以以类似的方式解决我的问题?

提前致谢!

4

1 回答 1

2

在第一种情况下,您想检查人员y是否包含在粉丝列表中,因此elem y a.

在第二种情况下,您想检查年份y是否等于电影的年份,因此您只需检查是否相等,a == y

filmsByYear y = map (\(a,_,_,_) -> a) $ filter (\(_,_,a,_) -> a == y) testDatabase

顺便说一句,如果你给 lambdas 命名,这段代码会更易读:

title (t, _, _, _) = t
fans (_, _, _, fs) = fs
year (_, _, y, _) = y

使用函数链更习惯用法:

filmsByFan f = map title $ filter (elem f . fans) testDatabase
filmsByYear y = map title $ filter ((== y) . year) testDatabase

到现在为止,您可能已经发现了一种模式,它本身可以很好地在高阶函数中捕获:

filmsBy func = map title $ filter func testDatabase
filmsByFan f = filmsBy (elem f . fans)
filmsByYear y = filmsBy ((== y) . year)
于 2013-04-20T15:07:32.653 回答