Haskell lambda中的非穷举模式

时间:2014-03-12 15:05:09

标签: database haskell lambda

我只需要以下代码的帮助。我相信我已经创建了正确的lambda函数来给出给定用户评级的电影的标题,以及该用户的评级。

但是,运行以下代码时似乎出现错误。错误是:lambda中的非详尽模式

我以前从未见过这种情况,并希望有人帮助我解决这个问题并让我更加了解将来如何解决这个问题。

谢谢!

import Data.List 
import Text.Printf

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",6), ("Bill",9), ("Ian",7), ("Kevin",9), ("Emma",4), ("Sam",5), ("Megan",4)]),
                ("The Fly","David Cronenberg",1986,[("Megan",4), ("Fred",7), ("Chris",5), ("Ian",0), ("Amy",5)]),
                ("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",2), ("Wally",8), ("Megan",9), ("Tim",5), ("Zoe",8), ("Emma",3)]),
                ("Titanic","James Cameron",1997,[("Zoe",7), ("Amy",2), ("Emma",5), ("Heidi",3), ("Jo",8), ("Megan",5), ("Olga",7), ("Tim",10)]),
                ("The Departed","Martin Scorsese",2006,[("Heidi",2), ("Jo",8), ("Megan",5), ("Tim",2), ("Fred",5)]),
                ("Aliens","Ridley Scott",1986,[("Fred",8), ("Dave",6), ("Amy",10), ("Bill",7), ("Wally",2), ("Zoe",5)]),
                ("Prometheus","Ridley Scott",2012,[("Garry",3), ("Chris",4), ("Emma",5), ("Bill",1), ("Dave",3)]),
                ("E.T. The Extra-Terrestrial","Steven Spielberg",1982,[("Ian",7), ("Amy",2), ("Emma",7), ("Sam",8), ("Wally",5), ("Zoe",6)]),
                ("The Birds","Alfred Hitchcock",1963,[("Garry",7), ("Kevin",9), ("Olga",4), ("Tim",7), ("Wally",3)]),
                ("Goodfellas","Martin Scorsese",1990,[("Emma",7), ("Sam",9), ("Wally",5), ("Dave",3)]),
                ("The Shawshank Redemption","Frank Darabont",1994,[("Jo",8), ("Sam",10), ("Zoe",3), ("Dave",7), ("Emma",3), ("Garry",10), ("Kevin",7)]),
                ("Gladiator","Ridley Scott",2000,[("Garry",7), ("Ian",4), ("Neal",6), ("Wally",3), ("Emma",4)]),
                ("The Green Mile","Frank Darabont",1999,[("Sam",3), ("Zoe",4), ("Dave",8), ("Wally",5), ("Jo",5)]),
                ("True Lies","James Cameron",1994,[("Dave",3), ("Kevin",4), ("Jo",0)]),
                ("Minority Report","Steven Spielberg",2002,[("Dave",5), ("Garry",6), ("Megan",2), ("Sam",7), ("Wally",8)]),
                ("The Wolf of Wall Street","Martin Scorsese",2013,[("Dave",6), ("Garry",6), ("Megan",0), ("Sam",4)]),
                ("War Horse","Steven Spielberg",2011,[("Dave",6), ("Garry",6), ("Megan",3), ("Sam",7), ("Wally",8), ("Zoe",8)]),
                ("Lincoln","Steven Spielberg",2012,[("Ian",3), ("Sam",7), ("Wally",3), ("Zoe",4), ("Liz",7), ("Megan",4)]),
                ("Vertigo","Alfred Hitchcock",1958,[("Bill",7), ("Emma",5), ("Zoe",9), ("Olga",6), ("Tim",10)]),
                ("The Terminal","Steven Spielberg",2004,[("Olga",3), ("Heidi",8), ("Bill",2), ("Sam",6), ("Garry",8)]),
                ("Jaws","Steven Spielberg",1975,[("Fred",3), ("Garry",0), ("Jo",3), ("Neal",9), ("Emma",7)]),
                ("Hugo","Martin Scorsese",2011,[("Sam",4), ("Wally",3), ("Zoe",4), ("Liz",7)])]         



userRatedFilms :: String -> [Film]
userRatedFilms username
     = filter(\(_,_,_,[(user,_)]) -> user == username) testDatabase

2 个答案:

答案 0 :(得分:1)

你可能想要像

这样的东西
filter ((username `elem`) . (\(_,_,_,xs) -> map fst xs)) testDatabase

但是请注意,你应该编写依赖于"全局变量"的函数,即使不是纯函数。 (因为你的下一个问题可能是这样的:我编写了982个使用testDatabase的函数,但现在我需要从某个文件中读取数据库,如何覆盖testDatabase?)

另一个注意事项:如果你想结合模式匹配和过滤,请考虑使用列表理解:

userRatedFilms films user = [ film | film@(_,_,_,[(u,_)]) <- films, u == user ]

这会发现这些影片的评分为user

答案 1 :(得分:0)

&#34;非详尽模式&#34;意味着某些案例&#34;通过&#34;。

我们说我们有一个简单的lambda - \[name] -> name==username。 我们将其转换为常规函数:

f :: [String] -> Bool
f (_,[name]) = name ==username

这是一项法律职能。但是当我们这样称呼时会发生什么:

f []

函数中唯一的模式是包含一个元素的列表,我们用空列表调用它。所以空列表&#34;落在&#34;我们得到了这个错误。

这意味着两件事之一:

  1. 也许你永远不需要另一种模式,而且错误是该函数是用非法参数调用的(例如,如果你知道另一个函数应该只返回带有一个项目的列表 - 所以bug可能是在那个功能)。
  2. 也许您只需要扩展功能定义,如下所示:\x -> case x of ...。还有一个名为LambdaCase的ghc扩展,它支持这种语法:\case [] -> 1; [x] ->2; ...