在Haskell中,如何将列表中的项目作为String返回?

时间:2014-02-26 13:49:17

标签: string list haskell

我有一种类型的电影如下:

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]]

任何帮助,为什么会发生这种情况,以及如何解决它将非常感激。

我对这种语言还很陌生,如果这不是最优雅的做法,那就道歉了。

提前致谢。

2 个答案:

答案 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)

除非您需要特定格式,否则以下代码就足够了,因为StringIntShow的实例:

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