Использование фильтра для элемента в списке? - PullRequest
2 голосов
/ 10 мая 2011

Я пытаюсь фильтровать по элементу в списке и печатать их построчно. Вот мой код:

data Car = Car String [String] Int [String]

testDatabase :: [Car]
testDatabase = [Car"Casino Royale" ["Daniel Craig"] 2006 ["Garry", "Dave", "Zoe", "Kevin", "Emma"],Car"Blade Runner" ["Harrison Ford", "Rutger Hauer"] 1982 ["Dave", "Zoe", "Amy", "Bill", "Ian", "Kevin", "Emma", "Sam", "Megan"]]



formatCarRow (Car a b c d) =  show a ++ " | " ++ concat [i ++ ", " | i <- init b] ++ last b ++ " | " ++ show c ++ " | " ++ concat [j ++ ", " | j <- init d] ++ last d



displayFilmsByYear :: String -> IO [()]
displayFilmsByYear chosenYear = mapM (putStrLn.formatFilmRow) [putStrLn(filter ((== chosenYear).y)) |  (w x y z) <- testDatabase] -- This is the code not working i think

Почему это не работает?

Ответы [ 2 ]

5 голосов
/ 11 мая 2011

Если вы хотите отфильтровать список, я рекомендую использовать функцию filter:)

data Car = Car String [String] Int [String]

year :: Car -> Int
year (Car _ _ y _) = y

filterByYear :: Int -> [Car] -> [Car]
filterByYear chosenYear cars = filter (\car -> year car == chosenYear) cars

showCar :: Car -> String
showCar car = undefined -- you can implement this how you like

displayCarsByYear :: Int -> IO ()
displayCarsByYear chosenYear = mapM_ (putStrLn . showCar) filteredCars
    where filteredCars = filterByYear chosenYear testDatabase

Кажется целесообразным объяснить несколько вещей здесь:

АнонимФункции : (\car -> year car == chosenYear) - анонимная функция.Он принимает один аргумент и называет его car.Затем он определяет, равен ли год этого автомобиля chosenYear.Я не написал явно сигнатуру типа этой функции, но это Car -> Bool.

Фильтрация : эту функцию я присвоил filter, чтобы она просматривала список Car s.Когда filter находит автомобили, для которых эта функция возвращает True, она помещает их в список результатов.Результат False означает, что автомобиль не проходит через фильтр.

Состав функции : (putStrLn . showCar) Эта функция сначала выполняет showCar, а затем используетputStrLn по результату showCar.

Где : вы увидите выражение where в конце моего кода.Это должно быть достаточно понятно, вы можете использовать операторы let или where для определения «локальных переменных».В качестве вкуса я предпочитаю использовать значение over let.

Список списков против фильтра : списки могут фильтровать список точно так же, как функция фильтра.Для функции f :: a -> Bool и списка xs :: [a]

filter f xs совпадает с [x | x <- xs, f x].В качестве вкуса я предпочитаю указывать filter в таких случаях, поскольку это очень ясно дает понять, что я фильтрую список.

См. Также LYAH # Карты и фильтры

-

Дополнительная рекомендация: используйте синтаксис записи

Вместо

data Car = Car String [String] Int [String]

Почему бы не

data Film = Film { name :: String
                 , actors :: [String]
                 , released :: Int
                 , characters :: [String]
                 }

(я не могу точно сказать, каким был ваш последний список строк)

Таким образом, вы можете создать фильм так:

lotr :: Film
lotr = Film { name = "Lord of the Rings"
            , actors = ["Elijah Wood", "Ian McKellen", "Orlando Bloom"]
            , released = 2001
            , characters = ["Frodo", "Sam", "Pippin", "Merry"]
            }

И у вас автоматически появится средство доступафункции

  • released :: Film -> Int
  • name :: Film -> String
  • и т. д.

См. также LYAH # Синтаксис записи

4 голосов
/ 10 мая 2011

Дело в следующем:

[putStrLn(filter ((== chosenYear).y)) |  (w x y z) <- testDatabase]

Вы еще не поняли понимание списка. То, что вы хотите:

[ (Car w x y z) | (Car w x y z) <- testDatabase, y==choosenYear]

Возможно.

С

 mapM (putStrLn . formatCarRow) 

вы уже заказали: формат и затем распечатайте каждый элемент из следующего списка . Следовательно, вклад StStrLn в понимание списка совершенно абсурден.

Обратите внимание, что putStrLn в некотором роде неверно: на самом деле он ничего не печатает! Он просто создает вещь, которая вызывает печать при выполнении в монаде ввода-вывода. Кажется, что это трудно понять, но скоро вы поймете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...