我有一种类型的电影如下:
type Film = (String, String, Int, [Rating])
type Rating = (String, Int)
我的目标是在数据库中列出一系列电影,如下:
myDatabase :: [Film]
myDatabase = [("Batman","Nolan",2012, [])]
在函数showFilms上,它将整个列表作为String值返回。
我的代码如下:
showFilms :: [Film] -> String
showFilms [] = []
showFilms (x:xs) = output: showFilms xs
where [[output]] = title ++ director ++ [(show year)] ++ [(show ratings)]
film = [film | (film) <- [x]]
title = [title | (title,director,year,ratings) <- film]
director = [director | (title,director,year,ratings) <- film]
year = [year | (title,director,year,ratings) <- film]
ratings = [ratings | (title,director,year,ratings) <- film]
它在WinGHCi上编译,但是当我输入除空数据库以外的任何内容时,我收到此错误:
*** Exception: HaskellCW.hs:32:29-95: Irrefutable pattern failed for pattern [[output]]
任何帮助,为什么会发生这种情况,以及如何解决它将非常感激。
我对这种语言还很陌生,如果这不是最优雅的做法,那就道歉了。
提前致谢。
答案 0 :(得分:3)
问题是title ++ director ++ [(show year)] ++ [(show ratings)]
计算字符串列表,这是一个字符列表列表,但模式[[output]]
仅匹配列表中只有一个字符串而另一个字符串string只包含一个字符。
在我看来,你想要做的是将x
变成一个字符串。为什么不这样做呢
showFilms :: [Film] -> String
showFilms [] = []
showFilms (x:xs) = output ++ showFilms xs
where output = title ++ director ++ (show year) ++ (show ratings)
(title, director, year, ratings) = x
答案 1 :(得分:2)
除非您需要特定格式,否则以下代码就足够了,因为String
和Int
是Show
的实例:
showFilms :: [Film] -> String
showFilms = show
请注意,您还可以从字符串中读取数据库,因为这些类型也是Read
的实例:
readFilms :: String -> [Film]
readFilms = read
如果你想要一种特定的格式,最好先考虑一部电影的Film -> String
,然后在你的数据库上映射该功能:
showFilm :: Film -> String
showFilm (title, director, year, ratings)
= title ++ " " ++ director ++ " [" ++ (show year) ++ "] [" ++ (show ratings) ++ "]"
showFilms' :: [Film] -> String
showFilms' = unlines . map showFilm