从文件中读取,然后使用数据作为列表

时间:2014-03-12 18:20:46

标签: list haskell io

所以我有一个名为testData的文本文件,其中包含以下数据:

[("Blade Runner","Ridley Scott",1982,[("Amy",6),("Bill",9),("Ian",7),("Kevin",9), 
("Emma",4),("Sam",5),("Megan",4)]),
("The Fly","David Cronenberg",1986,[("Megan",4),("Fred",7),("Chris",5),("Ian",0),("Amy",5)]),
("Psycho","Alfred Hitchcock",1960,[("Bill",4),("Jo",4),("Garry",8),("Kevin",7),
("Olga",8),("Liz",10),("Ian",9)]),
("Body Of Lies","Ridley Scott",2008,[("Sam",3),("Neal",7),("Kevin",2),("Chris",5),   ("Olga",6)]),
("Avatar","James Cameron",2009,[("Olga",2),("Wally",8),("Megan",9),("Tim",5),("Zoe",8),("Emma",3)]),
("Titanic","James Cameron",1997,[("Zoe",7), ("Amy",2), ("Emma",5), ("Heidi",3), ("Jo",8), ("Megan",5), ("Olga",7), ("Tim",10)]),
("The Departed","Martin Scorsese",2006,[("Heidi",2), ("Jo",8), ("Megan",5), ("Tim",2), ("Fred",5)]),
("Aliens","Ridley Scott",1986,[("Fred",8), ("Dave",6), ("Amy",10), ("Bill",7), ("Wally",2), ("Zoe",5)]),
("Prometheus","Ridley Scott",2012,[("Garry",3), ("Chris",4), ("Emma",5), ("Bill",1), ("Dave",3)]),
("E.T. The Extra-Terrestrial","Steven Spielberg",1982,[("Ian",7), ("Amy",2), ("Emma",7), ("Sam",8), ("Wally",5), ("Zoe",6)]),
("The Birds","Alfred Hitchcock",1963,[("Garry",7), ("Kevin",9), ("Olga",4), ("Tim",7), ("Wally",3)]),
("Goodfellas","Martin Scorsese",1990,[("Emma",7), ("Sam",9), ("Wally",5), ("Dave",3)]),
("The Shawshank Redemption","Frank Darabont",1994,[("Jo",8), ("Sam",10), ("Zoe",3), ("Dave",7), ("Emma",3), ("Garry",10), ("Kevin",7)]),
("Gladiator","Ridley Scott",2000,[("Garry",7), ("Ian",4), ("Neal",6), ("Wally",3), ("Emma",4)]),
("The Green Mile","Frank Darabont",1999,[("Sam",3), ("Zoe",4), ("Dave",8), ("Wally",5), ("Jo",5)]),
("True Lies","James Cameron",1994,[("Dave",3), ("Kevin",4), ("Jo",0)]),
("Minority Report","Steven Spielberg",2002,[("Dave",5), ("Garry",6), ("Megan",2), ("Sam",7), ("Wally",8)]),
("The Wolf of Wall Street","Martin Scorsese",2013,[("Dave",6), ("Garry",6), ("Megan",0), ("Sam",4)]),
("War Horse","Steven Spielberg",2011,[("Dave",6), ("Garry",6), ("Megan",3), ("Sam",7), ("Wally",8), ("Zoe",8)]),
("Lincoln","Steven Spielberg",2012,[("Ian",3), ("Sam",7), ("Wally",3), ("Zoe",4), ("Liz",7), ("Megan",4)]),
("Vertigo","Alfred Hitchcock",1958,[("Bill",7), ("Emma",5), ("Zoe",9), ("Olga",6), ("Tim",10)]),
("The Terminal","Steven Spielberg",2004,[("Olga",3), ("Heidi",8), ("Bill",2), ("Sam",6), ("Garry",8)]),
("Jaws","Steven Spielberg",1975,[("Fred",3), ("Garry",0), ("Jo",3), ("Neal",9), ("Emma",7)]),
("Hugo","Martin Scorsese",2011,[("Sam",4), ("Wally",3), ("Zoe",4), ("Liz",7)])]

我正在读这样的文件:

input2 <- readFile "C:/Users/Alex/Dropbox/Uni Work Year 2/Year 2/MATHFUN/testData.txt"
let testDatabase = input2

现在,我有另一个在IO中调用的函数,名为addFilms,它有参数String,String,Int和[Film]。 [电影]是我数据库的定义。

然而,当我尝试调用fucntion时,我收到此错误:

HaskellCW.hs:155:47:
Couldn't match type `Char' with `(String, String, Int, [Rating])'
Expected type: [Film]
  Actual type: String
In the fourth argument of `addFilm', namely `testDatabase'
In the first argument of `putStrLn', namely
  `(addFilm title director year testDatabase)'
In a stmt of a 'do' block:
  putStrLn (addFilm title director year testDatabase)

任何人都可以帮我这个吗?我需要将数据库保持为[Film]类型。在下面找到我的代码。

type Film   = (String, String, Int, [Rating])

testDatabase :: [Film]

addFilm :: String -> String -> Int -> [Film] -> String
addFilm nTitle nDirector nYear films    | [nTitle] == title = show films
                                    | otherwise         = show (films ++ [newfilm])
                                 where   newfilm        = (nTitle, nDirector, nYear, ratings)
                                         title          = [title | (title,director,year,ratings) <- films]
                                         ratings        = []

main :: IO ()
main = do
putStrLn "Please Enter Your Name: "
input <- getLine
let userName = input
putStrLn ("Your name is: " ++ userName)
input2 <- readFile "C:/Users/Alex/Dropbox/Uni Work Year 2/Year 2/MATHFUN/testData.txt"
let testDatabase = input2
putStrLn testDatabase

putStrLn "Type a function to perform. List of Functions: "
putStrLn "addFilm, showFilms, getDirector, getHighRatings, getAverageDirector, getUserRatings"

str <- getLine
if  str == "addFilm" then do
    putStrLn "Function addFilm"
    putStrLn "Enter film title: "
    input1 <- getLine
    let title = input1
    putStrLn "Enter film director: "
    input2 <- getLine
    let director = input2
    putStrLn "Enter film year: "
    input3 <- getLine
    let year = (read input3 :: Int)
    putStrLn (addFilm title director year testDatabase)
else if str == "showFilms" then do
    putStrLn "Function showFilms"
else if str == "getDirector" then do
    putStrLn "Function getDirector"
else if str == "getHighRatings" then do
    putStrLn "Function getHighRatings"
else if str == "getAverageDirector" then do
    putStrLn "Function getAverageDirector"
else if str == "getUserRatings" then do
    putStrLn "Function getUserRatings"
else do
    putStrLn "Thankyou for using the system, saving the database."
    writeFile "C:/Users/Alex/Dropbox/Uni Work Year 2/Year 2/MATHFUN/testData.txt" testDatabase

1 个答案:

答案 0 :(得分:4)

您的字符串包含实际Haskell信息的字符串表示形式:1Int,但"1"String。您无法将String传递给接受[Film]的函数,原因相同5 + 4 + "6"不是有效表达式。

使用read

input2 <- readFile "C:/Users/Alex/Dropbox/Uni Work Year 2/Year 2/MATHFUN/testData.txt"
let testDatabase = read input2 :: [Film]

它将解析输入并将其转换为[Film]read基本上与show相反:它获取Haskell值的字符串表示并返回实际值。

请注意,类型签名在这里可能至关重要。如果你写1 + read "2" Haskell可以从上下文中推断出"2"代表Int,但仅read "2"会导致编译错误,因为"2"可能意味着例如,数字2和字符串"2",以及Haskell将无法推断其类型。

您可以详细了解readshow here