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最初のケースでは、 personがファンのリストに含まれているかどうかを確認したいので、 elem y a.

2 番目のケースでは、 year が映画の年y等しいa == yかどうかを確認したいので、単純に等しいかどうかを確認します。

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

ちなみに、ラムダ名を指定すると、このコードは読みやすくなります。

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 に答える