1

現在、私の haskell プログラムで 2 つの主な質問を解決しようとしています。

  1. 特定のユーザーがファンであるすべての映画を表示する
  2. 特定の期間 (つまり、特定の開始年と終了年の間) にリリースされた特定の俳優のすべての映画を表示します。

これは私が現在使用しているサンプル データベースです。

type Title = String
type Cast = String
type Year = Int
type Fans = String

type Film = (Title, [Cast], Year, [Fans])
type Database = [Film]

testDatabase :: Database
testDatabase = [("Casino Royale", ["Daniel Craig", "Eva Green", "Judi Dench"], 2006,    ["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"], 2002, ["Zoe", "Heidi", "Jo", "Emma", "Liz", "Sam", "Olga", "Kevin", "Tim"])]    

データベースははるかに大きくなりますが、スペース上の理由から、一部を省略しました。

  • このデータベースを使用して、上記の 2 つの質問に答えるために必要な関数を作成するにはどうすればよいですか?
4

4 に答える 4

1

これはうまくいくはずです:

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"], 2006, ["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"], 2002, ["Zoe", "Heidi", "Jo", "Emma", "Liz", "Sam", "Olga", "Kevin", "Tim"])]

inCast :: Actor -> Film -> Bool
inCast givenActor (_, cast, _, _) = any (\actor -> actor == givenActor) cast

inPeriod :: Period -> Film -> Bool
inPeriod (periodStart, periodEnd) (_, _, year, _) = periodStart <= year && year <= periodEnd

inCastAndPeriod :: Actor -> Period -> Film -> Bool
inCastAndPeriod actor period film = inCast actor film && inPeriod period film

isFan :: Fan -> Film -> Bool
isFan givenFan (_, _, _, fans) = any (\fan -> fan == givenFan) fans

allFilmsThatAGivenUserIsAFanOf :: Fan -> [Film]
allFilmsThatAGivenUserIsAFanOf givenFan = filter (isFan givenFan) testDatabase

allTheFilmsOfAGivenActorThatWereReleasedDuringAParticularPeriod :: Actor -> Period -> [Film]
allTheFilmsOfAGivenActorThatWereReleasedDuringAParticularPeriod givenActor givenPeriod = filter (inCastAndPeriod givenActor givenPeriod) testDatabase

幸運を!

于 2013-04-03T16:43:43.590 に答える
0

型をレコードとして宣言するFilmと、フィールド アクセサーを無料で取得できるため、フィルターが読みやすくなります (また、Fans単一ではありませんFanか?)。

type Title = String
type Cast = String
type Year = Int
type Fan = String

data Film = Film { filmTitle :: Title
                 , filmCast  :: [Cast]
                 , filmYear  :: Year
                 , filmFans  :: [Fan]
                 }

type Database = [Film]

最初の問題はFilm、特定のユーザーが( s のFanタイトルではなく) である s が必要であると述べています。Film

fanOfFilms :: Fan -> Database -> [Film]
fanOfFilms fan = filter (elem fan . filmFans)

2 番目の問題は同じ方法で解決できますが、述語はより複雑になります。

periodActorOfFilms :: Cast -> Year -> Year -> Database -> [Film]
periodActorOfFilms actor startYear endYear =
    filter $ \film -> and [ actor `elem` filmCast film
                          , startYear <= filmYear film
                          , endYear >= filmYear film
                          ]
于 2013-04-03T16:50:32.193 に答える