简体   繁体   English

Haskell在元组中打印列表的所有元素

[英]Haskell printing all elements of a list within tuple

I'm trying to print all elements of the Fans list for a given film title for example all fans of "Avatar" not quite sure how to filter this and display the correct elements as a string. 我正在尝试打印给定电影标题的“粉丝”列表中的所有元素,例如“阿凡达”的所有粉丝都不太确定如何过滤该元素并将正确的元素显示为字符串。 Here is the type definition of the program with some of the test data. 这是带有一些测试数据的程序的类型定义。

import Data.Char
import Data.List

--types
type Title = String
type Director = String
type Year = Int
type Fans = [String]

type Film = (Title, Director, Year, Fans)

type Database = [Film]

testDatabase :: [Film]
testDatabase = [
 ("Blade Runner", "Ridley Scott", 1982, ["Zoe", "Heidi", "Jo", "Kate", "Emma", "Liz", "Sam", "Olga", "Tim"]),
 ("The Fly", "David Cronenberg", 1986, ["Garry", "Dave", "Zoe", "Kevin", "Emma"]),
 ("Body Of Lies", "Ridley Scott", 2008, ["Bill", "Olga", "Tim", "Zoe", "Paula"]),
 ("Avatar", "James Cameron", 2009, ["Dave", "Amy", "Liz"]),
 ("Titanic", "James Cameron", 1997, ["Zoe", "Emma", "Paula", "Liz", "Olga", "Dave"])]

You're really shooting yourself in the foot by using type synonyms for everything. 通过对所有内容使用类型同义词,您真的在脚下射击。 data Film = Film Title Director Year Fans is much better than using a tuple in this case. 在这种情况下, data Film = Film Title Director Year Fans比使用元组要好得多。 Defining a separate Film data type brings the semantic difference between a Film and a tuple of Title , Director , Year , and Fans into the type system. 定义一个单独的Film数据类型会将FilmTitleDirectorYearFans元组之间的语义差异引入类型系统。 This means that you can define instances for it (like Show or Eq ) that will behave in a specific way that is different from what a tuple would give you. 这意味着您可以为其定义实例(例如ShowEq ),这些实例将以不同于元组给您的方式的特定方式运行。 It also causes the compiler to reject code that (potentially accidentally) mixes a tuple that happens to have the type (String,String,Int,[String]) with an actual Film . 它还会导致编译器拒绝(可能是偶然地)将恰好具有类型(String,String,Int,[String])类型的元组与实际Film This adds safety, which is one of the main reasons to use Haskell in the first place. 这增加了安全性,这是首先使用Haskell的主要原因之一。

That said, listing the fans only is pretty simple either way: 也就是说,仅列出粉丝就很简单:

listFans :: Film -> String
-- data way
listFans (Film _ _ _ fans) = intersperse ',' fans
-- tuple way
listFans (_,_,_,fans) = intersperse ',' fans

Next, we need a lookupFilm :: Database -> Title -> Maybe Film to find the film we want. 接下来,我们需要一个lookupFilm :: Database -> Title -> Maybe Film来找到我们想要的电影。 We need the Maybe because the Film might not be in the Database . 我们Maybe需要,因为Film可能不在Database

lookupFilm :: Database -> Title -> Maybe Film
lookupFilm db t = find (\(Film t' _ _ _) -> t == t') db

Note that this doesn't "print" the strings, it just returns them, so you would need putStrLn . listFans :: Film -> IO () 请注意,这不会“打印”字符串,而只是返回它们,因此您需要putStrLn . listFans :: Film -> IO () putStrLn . listFans :: Film -> IO () to actually output them. putStrLn . listFans :: Film -> IO ()实际输出它们。

If you always lookup films by their title, you might as well use a Map Title Film from Data.Map . 如果您总是按标题查找电影,则最好使用Data.Map中的“ Map Title Film

Lastly: be sure you understand how find and intersperse work; 最后:确保您了解findintersperse工作的方式; Data.List is like being given a fish, but you need to learn how to fish for yourself in order to tackle more complex problems as they arise. Data.List就像一条鱼,但是您需要学习如何自己捕鱼,以便解决出现的更复杂的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM