2013-04-20 5 views
0

У меня возникли проблемы выводящий определенные биты информации из этой конкретной базы данных:Haskell высшего порядка Функция

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 

Но это не компилируется .. . Это потому, что тип Год задан как Int? Если это так, то решение моей проблемы аналогично?

Заранее благодарен!

ответ

2

В первом случае, вы хотите, чтобы проверить человек y ли содержащиеся в списке поклонников, поэтому elem y a.

Во втором случае, вы хотите проверить, является ли 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) 
+0

Я внес изменения в код, но это ошибка я получение -------------------- Нет экземпляра для (Eq ([Год] -> Bool)) , связанный с использованием '== ' Возможное исправление: add объявление экземпляра для (Eq ([Year] -> Bool)) В выражении: elem a == y В первом аргументе 'filter ', а именно ' (\ (_, _, a, _) - > elem a == y) ' Во втором аргументе '($)', а именно ' filter (\ (_, _, a, _) -> elem a == y) testDatabase ' – user2240649

+0

Я протестировал его, и я уверен оно работает. Как вы называете эту функцию? – Thomas

+0

Не беспокойтесь, у меня сейчас работает! Большое спасибо за ваш вклад! – user2240649

Смежные вопросы