2016-03-04 59 views
1

我想制作一个函数,返回给定范围内的电影列表。例如,假设我有电影的名单,我想找到的是,在几年冒出来的所有的电影2010年至2014年,这里是我的代码:非穷举模式:Int - > Int - > [电影] - > [电影]

type Rating = (String, Int) 
type Title = String 
type Director = String 
type Year = Int 
type Film = (Title, Director, Year,[Rating]) 

testDatabase :: [Film] 
testDatabase = [("Blade Runner","Ridley Scott",1982,[("Amy",5), ("Bill",8), ("Ian",7), ("Kevin",9), ("Emma",4), ("Sam",7), ("Megan",4)]), 
      ("The Fly","David Cronenberg",1986,[("Megan",4), ("Fred",7), ("Chris",5), ("Ian",0), ("Amy",6)]), 
      ("Psycho","Alfred Hitchcock",1960,[("Bill",4), ("Jo",4), ("Garry",8), ("Kevin",7), ("Olga",8), ("Liz",10), ("Ian",9)]), 
      ("Body Of Lies","Ridley Scott",2008,[("Sam",3), ("Neal",7), ("Kevin",2), ("Chris",5), ("Olga",6)]), 
      ("Avatar","James Cameron",2009,[("Olga",1), ("Wally",8), ("Megan",9), ("Tim",5), ("Zoe",8), ("Emma",3)]), 
      ("Titanic","James Cameron",1997,[("Zoe",7), ("Amy",1), ("Emma",5), ("Heidi",3), ("Jo",8), ("Megan",5), ("Olga",7), ("Tim",10)]), 
      ("The Departed","Martin Scorsese",2006,[("Heidi",3), ("Jo",8), ("Megan",5), ("Tim",3), ("Fred",5)]), 
      ("Aliens","Ridley Scott",1986,[("Fred",9), ("Dave",6), ("Amy",10), ("Bill",7), ("Wally",1), ("Zoe",5)]), 
      ("Kingdom Of Heaven","Ridley Scott",2005,[("Garry",3), ("Chris",7), ("Emma",5), ("Bill",1), ("Dave",3)]), 
      ("E.T. The Extra-Terrestrial","Steven Spielberg",1982,[("Ian",9), ("Amy",1), ("Emma",7), ("Sam",8), ("Wally",5), ("Zoe",6)]), 
      ("Bridge of Spies","Steven Spielberg",2015,[("Fred",3), ("Garry",4), ("Amy",10), ("Bill",7), ("Wally",6)]), 
      ("Vertigo","Alfred Hitchcock",1958,[("Bill",8), ("Emma",5), ("Garry",1), ("Kevin",6), ("Olga",6), ("Tim",10)]), 
      ("The Birds","Alfred Hitchcock",1963,[("Garry",7), ("Kevin",8), ("Olga",4), ("Tim",8), ("Wally",3)]), 
      ("Jaws","Steven Spielberg",1975,[("Fred",3), ("Garry",0), ("Jo",3), ("Neal",9), ("Emma",7)]), 
      ("The Martian","Ridley Scott",2015,[("Emma",7), ("Sam",8), ("Wally",5), ("Dave",10)]), 
      ("The Shawshank Redemption","Frank Darabont",1994,[("Jo",8), ("Sam",10), ("Zoe",4), ("Dave",7), ("Emma",3), ("Garry",10), ("Kevin",7)]), 
      ("Gladiator","Ridley Scott",2000,[("Garry",7), ("Ian",4), ("Neal",5), ("Wally",3), ("Emma",4)]), 
      ("The Green Mile","Frank Darabont",1999,[("Sam",3), ("Zoe",4), ("Dave",7), ("Wally",5), ("Jo",5)]), 
      ("True Lies","James Cameron",1994,[("Dave",3), ("Kevin",10), ("Jo",0)]), 
      ("Super 8","J J Abrams",2011,[("Dave",7), ("Wally",3), ("Garry",5), ("Megan",4)]), 
      ("Minority Report","Steven Spielberg",2002,[("Dave",6), ("Garry",6), ("Megan",2), ("Sam",7), ("Wally",8)]), 
      ("War Horse","Steven Spielberg",2011,[("Dave",6), ("Garry",6), ("Megan",3), ("Sam",7), ("Wally",8), ("Zoe",8)]), 
      ("The Terminal","Steven Spielberg",2004,[("Olga",8), ("Heidi",8), ("Bill",2), ("Sam",6), ("Garry",8)]), 
      ("Star Wars: The Force Awakens","J J Abrams",2015,[("Olga",6), ("Zoe",6), ("Bill",9), ("Sam",7), ("Wally",8), ("Emma",8)]), 
      ("Hugo","Martin Scorsese",2011,[("Sam",9), ("Wally",3), ("Zoe",5), ("Liz",7)])] 

filmsInRangeOfYears :: Int -> Int -> [Film] -> [Film] 
filmsInRangeOfYears _ _ [] = [] 
filmsInRangeOfYears minYear maxYear [(title, director, year, rating)] = filter(\(_,_,year,_) -> year >= minYear && year <=maxYear) [(title, director, year, rating)] 

但是,我一直recieving这个错误

**Non-exhaustive patterns in function filmsInRangeOfYears** 

环顾在线后,我仍然不明白如何解决这个错误;从我的理解我需要更多的模式来填补所有可能的案例,但我用过的仍然给了我相同的结果。如果有人能帮助我,这我会很greatfull

编辑:增加了电影

的一个例子列表
+2

你能想到'filmsInRangeOfYears'的示例输入与你写的任何一种模式都不匹配吗? –

+0

@IanHenry你好吗 – hao

回答

1

我对你想要在这里做什么感到有点困惑。我认为这是你的初衷:

filmsInRangeOfYears :: Int -> Int -> [Film] -> [Film] 
filmsInRangeOfYears _ _ [] = [] 
filmsInRangeOfYears minYear maxYear ((title, director, year, rating):tail) = 
    if year >= minYear && year <= maxYear 
    then (title, director, year, rating):filmsInRangeOfYears minYear maxYear tail 
    else filmsInRangeOfYears minYear maxYear tail 

在那里没有空间让你使用filterfilter已经这样做了这一切,所以只是把你的功能分为

filmsInRangeOfYears :: Int -> Int -> [Film] -> [Film] 
filmsInRangeOfYears minYear maxYear films = filter (\(_,_,year,_) -> year >= minYear && year <=maxYear) films 

回到你的错误的原因,详尽地匹配列表,你平时对待两种情况:

a [] = ... 
a (head:tail) = ... 

这就是空表,非空列表,匹配为headtail。这两种模式涵盖了列表可能需要的所有可能值。在你的代码中,你为空列表编写规则,并为其中包含单个元素的列表编写规则,该元素的组件匹配到title,director等等。你还有一个病例要治疗,长度> = 2的列表。

尽管如此,仍然错误,考虑到filter的误解。这里

2

在第一行:

filmsInRangeOfYears _ _ [] = [] 

你对匹配空列表。在第二行(忽略了一些细节):

filmsInRangeOfYears minYear maxYear [(...)] = ... 

要针对由一个项目列表匹配。您错过了与x:xs的比赛:头部和非空尾。

2

问题

的问题是,你是图形作单列表匹配。 当您调用该函数时,它首先尝试将该模式与空列表进行匹配,如果不匹配,则它将移至单例列表的下一个模式,并且如果列表中有多个元素,则它将移至下一个模式,在这种情况下没有因此导致错误。

解决方案

filmsInRangeOfYears :: Int -> Int -> [Film] -> [Film] 
filmsInRangeOfYears minYear maxYear = filter(\(_,_,year,_) -> year >= minYear && year <= maxYear) 

解释 - 模式匹配的两个参数时,类型签名因为我们的函数体使用过滤功能,需要一个断言,如果名单有三个

我们只给它一个谓词,我们将作为回报得到一个部分应用的函数这个函数需要一个列表,就像我们的filmsInRangeOfYears函数是它的最后一个参数一样。此方法与执行以下操作相同。 filmsInRangeOfYears minYear maxYear xs = filter(...) xs

注意我们也可以删除空列表模式匹配,因为如果没有元素满足谓词,过滤器将返回一个空列表。

相关问题