いくつかの間違い:
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")
(Title cast year fans)
あなたが意味したとき、ここにありました(title,cast,year,fans)
。
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]
ここでは、リスト内包表記を使用して、末尾にセパレーターを含む文字列のリストを作成し、concat
それらを結合しています。最後にスペアを取得しますが", "
、キャストと年の間に 1 つ必要なので問題ありません。
length fans
これで、ファンの数を表示するために使用して、それをまとめることができます。
displayAllFilms' :: [Film] -> String -> String
displayAllFilms' [] filmString = filmString
displayAllFilms' ((title,cast,year,fans):films) filmString =
displayAllFilms' films (filmString ++ "\n" ++ title ++ ", " ++ listStuff cast ", " ++ (show year) ++ ", " ++ show (length fans))
これは次のようにテストされます
>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 と 2 番目の結果intercalate
が便利です。
> 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]
しかし、それはより良いだろう
showDatabase :: Database -> String
showDatabase = unlines.map showFilm
showFilm
それぞれのフィルムで使用したいだけで、とにかく見やすいunlines
という意味です。intercalate "\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