Database Haskell格式化和显示数据

Database Haskell格式化和显示数据,database,haskell,formatting,Database,Haskell,Formatting,在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] tes

在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"], 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"])
上面是示例数据库-最终目标是编写一个函数“displayAllFilms”,输出以下内容:

皇家赌场,丹尼尔·克雷格,伊娃·格林,朱迪·丹奇,2006年5月

《牛仔与外星人》,哈里森·福特,丹尼尔·克雷格,奥利维亚·王尔德,2011年,第6期

注:制作过程很重要,每部电影都会在单独的行上显示其信息,并在结尾显示风扇数量,而不是风扇列表

这是我解决这个问题的尝试-

displayAllFilms :: [Film] -> String -> String
displayAllFilms [] filmString = filmString
displayAllFilms ((Title cast year fans _):films) filmString = displayAllFilms films (filmString ++ title ++ "\n" ++ (show cast) ++ "\n" ++ (show year) ++ "\n") 
但它似乎没有编译,但我似乎找不到任何错误与我的代码…是一个类型错误

提前谢谢

有几个错误:

testDatabase :: Database
testDatabase = [("Casino Royale", ["Daniel Craig", "Eva Green", "Judi Dench"], 2006,          ["Garry", "Dave", "Zoe", "Kevin", "Emma"]),
    -- indentation should be consistent - this next line was too far left:
    ("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"])]
你忘了在列表末尾有一个紧括号
]

displayAllFilms :: [Film] -> String -> String
displayAllFilms [] filmString = filmString
displayAllFilms ((title,cast,year,fans):films) filmString = displayAllFilms films (filmString ++ title ++ "\n" ++ (show cast) ++ "\n" ++ (show year) ++ "\n")
这里有
(片名演员年粉丝)
,你的意思是
(片名演员年粉丝)

Haskell区分大小写,大写字母表示
Title
是一个构造函数,但您的意思是它是一个变量。 因为您的
Film
类型是一个元组,所以这里的逗号也需要是元组

获得正确的输出 现在,这将为您提供

putStrLn $ displayAllFilms testDatabase "=========="
==========Casino Royale
["Daniel Craig","Eva Green","Judi Dench"]
2006
Cowboys & Aliens
["Harrison Ford","Daniel Craig","Olivia Wilde"]
2011
Catch Me If You Can
["Leonardo DiCaprio","Tom Hanks"]
2002
现在这与您所需的输出不匹配

Casino Royale, Daniel Craig, Eva Green, Judi Dench, 2006, 5
因为这里有新行而不是逗号,还有你不想要的括号

listStuff:: [String] -> String -> String
listStuff strings separator = concat [string++separator| string <-strings]
测试结果是

>putStrLn $ displayAllFilms' testDatabase ""

Casino Royale, Daniel Craig, Eva Green, Judi Dench, 2006, 5
Cowboys & Aliens, Harrison Ford, Daniel Craig, Olivia Wilde, 2011, 6
Catch Me If You Can, Leonardo DiCaprio, Tom Hanks, 2002, 9
稍微整理一下代码 我不认为
displayAllFilms
需要递归-我们可以重用
listStuff
,但是有一个库函数可以做更多我们想要的事情。如果您在hoogle上搜索
[String]->String->String
,您会得到这些结果http://www.haskell.org/hoogle/?hoogle=[String]+-%3E+String+-%3E+String和第二个,
interlate
很方便:

> intercalate "_" ["Hello","Mum,","how","are","you?"]
"Hello_Mum,_how_are_you?"
你必须把

import Data.List
在您的代码的顶部使用它。所以现在我们可以做了

commas :: [String] -> String
commas = intercalate ", "
所以我们可以显示一个单独的电影,然后用它来显示电影列表

showFilm :: Film -> String
showFilm (title,cast,year,fans) = commas [title, commas cast, show year, show (length fans)]
我们可以写

showDatabase :: Database -> String
showDatabase fs = intercalate "\n" [showFilm f | f<-fs]
因为你只想在每一部电影上使用
showFilm
,然后
unlines
,这意味着
插入“\n”
,但对眼睛来说更容易

> putStrLn $ showDatabase testDatabase
Casino Royale, Daniel Craig, Eva Green, Judi Dench, 2006, 5
Cowboys & Aliens, Harrison Ford, Daniel Craig, Olivia Wilde, 2011, 6
Catch Me If You Can, Leonardo DiCaprio, Tom Hanks, 2002, 9

感谢您的帮助,它现在可以编译了,但是我应该输入什么来调用要运行的函数呢?[Film]->String->String我输入什么[Film],输入什么字符串输出字符串?这对我帮助很大,非常感谢!最后一个问题。我在WinGHCI环境中运行此代码,但它没有实现“\n”函数。这是因为它必须在I/o环境中吗?@user2240649实际上我在WinGHCI中测试它。您遇到了什么错误?噢-您的意思是它显示
\n
而不是开始换行吗?这就是为什么我要做
putStrLn$
。它将字符串转换为打印它的程序,用实际换行符替换
\n
。这就是问题所在吗?@user2240649我想厚着脸皮说,你可以用向上箭头说“这很有帮助”,用勾号说“这是我需要的答案!”:)
showDatabase :: Database -> String
showDatabase = unlines.map showFilm
> putStrLn $ showDatabase testDatabase
Casino Royale, Daniel Craig, Eva Green, Judi Dench, 2006, 5
Cowboys & Aliens, Harrison Ford, Daniel Craig, Olivia Wilde, 2011, 6
Catch Me If You Can, Leonardo DiCaprio, Tom Hanks, 2002, 9