Jam*_*ieB -1 haskell file input
现在我有两种类型:
type Rating = (String, Int)
type Film = (String, String, Int, [Rating])
Run Code Online (Sandbox Code Playgroud)
我有一个包含此数据的文件:
"Blade Runner"
"Ridley Scott"
1982
("Amy",5), ("Bill",8), ("Ian",7), ("Kevin",9), ("Emma",4), ("Sam",7), ("Megan",4)
"The Fly"
"David Cronenberg"
1986
("Megan",4), ("Fred",7), ("Chris",5), ("Ian",0), ("Amy",6)
Run Code Online (Sandbox Code Playgroud)
我怎样才能查看将所有条目存储到FilmDatabase = [Film]之类的文件?
Haskell提供了一种草绘您的方法的独特方式.从你所知道的开始
module Main where
type Rating = (String, Int)
type Film = (String, String, Int, [Rating])
main :: IO ()
main = do
films <- readFilms "ratings.dat"
print films
Run Code Online (Sandbox Code Playgroud)
试图将这个程序加载到ghci中会产生
films.hs:8:12: Not in scope: `readFilms'
它需要知道是什么readFilms,所以添加足够的代码来继续前进.
readFilms = undefined
Run Code Online (Sandbox Code Playgroud)
这是一个应该做与Film数据相关的功能.获取此代码(使用:reload命令或:r简称)
films.hs:9:3:
Ambiguous type variable `a0' in the constraint:
(Show a0) arising from the use of `print'
...
类型print是
Prelude> :t print print :: Show a => a -> IO ()
换句话说,print采用一个非正式地知道如何显示自身的参数(即,将其内容转换为字符串)并创建一个I/O操作,该操作在执行时输出该字符串.这或多或少是你期望print的工作方式:
Prelude> print 3 3 Prelude> print "hi" "hi"
我们知道我们想要从文件中print获取Film数据,但是,尽管很好,ghc无法读懂我们的想法.但是在添加了类型提示之后
readFilms :: FilePath -> Film
readFilms = undefined
Run Code Online (Sandbox Code Playgroud)
我们得到一个新的错误.
films.hs:8:12:
Couldn't match expected type `IO t0'
with actual type `(String, String, Int, [Rating])'
Expected type: IO t0
Actual type: Film
In the return type of a call of `readFilms'
In a stmt of a 'do' expression: films <- readFilms "ratings.dat"
该错误告诉您编译器对您的故事感到困惑.你说readFilms应该给它一个Film,但是你调用它的方式main,计算机应该首先执行一些I/O 然后返回Film数据.
在Haskell中,这是纯字符串(例如"JamieB")和副作用之间的区别,比如在提示您输入Stack Overflow用户名后从键盘读取输入.
所以现在我们知道我们可以草绘readFilms为
readFilms :: FilePath -> IO Film
readFilms = undefined
Run Code Online (Sandbox Code Playgroud)
并编译代码!(但我们还不能运行它.)
要挖掘另一层,假装单个电影的名称是唯一的数据,ratings.dat并在其他地方放置占位符,以保持typechecker的快乐.
readFilms :: FilePath -> IO Film
readFilms path = do
alldata <- readFile path
return (alldata, "", 0, [])
Run Code Online (Sandbox Code Playgroud)
此版本编译,您甚至可以通过输入mainghci提示符来运行它.
在dave4420中,答案是关于其他功能使用的很好的提示.可以把上面的方法想象成拼凑拼图,其中各个部分都是功能.为了使您的程序正确,所有类型必须放在一起.如上所述,您可以通过采取小的babysteps来向最终的工作程序取得进展,如果您的草图中有错误,typechecker会通知您.
需要弄清楚的事情:
String)中的年份转换为Int与您的定义合作Film?readFilms累积并返回Film数据列表?这是家庭作业吗?
您可能会发现这些函数很有用:
readFile :: FilePath -> IO Stringlines :: String -> [String]break :: (a -> Bool) -> [a] -> ([a], [a])dropWhile :: (a -> Bool) -> [a] -> [a]null :: [a] -> Boolread :: Read a => String -> a请记住,这String是一样的[Char].
一些线索:
dropWhile null 将从列表的开头摆脱空行break null 将列表拆分为非空行的前导,以及列表的其余部分| 归档时间: |
|
| 查看次数: |
828 次 |
| 最近记录: |