我希望用户输入一个元组列表,在其上搜索一个像这样的密钥,我可以这样说
data BookInfo = Book Int String [String]
deriving(Show)
findbook :: [BookInfo] -> Int -> BookInfo
findbook vs key = (booker (vs!!(bookFinding vs key 0 (length vs))) key)
getBookInfo = do
putStrLn "Enter book id :"
k <- read
putStrLn "Enter book name : "
r <- getLine
putStrLn "Enter book subject :"
m <- getLine
let Book book = enter k r [m]
return book
main = do
putStr "Enter you first info is :"
v <- getBookInfo
let Book vs = v:[]
c <- getLine
if c == "N"
then
putStr "You done"
else
Book booke = getBookInfo
vs = booke:vs
putStr "Do you want to search ? :"
m <- getch
if m == 'y'
then
putStr " Enter your key :"
s <- readNum
let Book w = findBook vs s
putStrLn" The result is: " ++ show(w)
Run Code Online (Sandbox Code Playgroud)
但它给了我一个错误:
The last statement in do must be m <- getch
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
看起来你正在尝试编写一个程序来将书籍列表读入某种数据库,然后搜索书籍.您可以从存储书信息的数据类型开始:
data BookInfo = Book Int String [String] deriving (Show)
Run Code Online (Sandbox Code Playgroud)
现在让我们看看你的函数,它从用户那里读取书籍信息.
getBookInfo = do
putStrLn "Enter book id :"
k <- read
putStrLn "Enter book name : "
r <- getLine
putStrLn "Enter book subject :"
m <- getLine
let Book book = enter k r [m]
return book
Run Code Online (Sandbox Code Playgroud)
我为你修改了你的缩进(这里是一个提示:使用四个空格进行缩进!)但还有其他问题:
这条线k <- read没有任何意义.读取的类型是,read :: Read a => String -> a但您正在使用它,就好像它是一个I/O操作.你需要这个功能readLn.
这条线let Book book = enter k r [m]没有任何意义.看起来你已经习惯用C语言或Java语言编写,你必须指定类型.你不必在Haskell中做到这一点!此外,该enter功能是不必要的.你可以写let book = Book k r [m],这将工作正常.实际上,您根本不需要临时变量book- 您可以创建Book并在一行中返回所有临时变量.
所以你可以写:
getBookInfo :: IO BookInfo
getBookInfo = do
putStrLn "Enter book id: "
bookid <- readLn
putStrLn "Enter book name: "
name <- getLine
putStrLn "Enter book subject: "
subject <- getLine
return (Book bookid name [subject])
Run Code Online (Sandbox Code Playgroud)
现在编译好了.请注意,我还添加了一个类型声明(可选).
你的下一个功能main是试图做太多.它包含获取书籍列表的所有规则以及搜索它们的规则.这是两个单独的任务,因此它们应该在两个单独的功能中.那么让我们编写一个获取书籍列表的函数:
getBookList :: IO [BookInfo]
getBookList = do
putStr "Any more books? "
answer <- getLine
if answer == "N"
then return []
else do
book <- getBookInfo
books <- getBookList
return (book:books)
Run Code Online (Sandbox Code Playgroud)
花点时间了解这个功能是如何工作的.首先,它会询问您是否还有其他书籍需要输入.如果你说"N"然后它返回空列表,你就完成了.否则,它会做一些神奇的事情 - 首先,它要求getBookInfo获取一本书的信息.然后它自称为获得书籍清单!这是递归的一个例子.最后,它将第一本书添加到书籍列表中,并返回整个列表.
你现在应该自己编写程序的其余部分.我可能会在一天左右的时间内重新审视这个答案,以增加更多细节.如果你发表评论让我知道你的尝试是什么,以及你遇到困难的地方,我更有可能这样做.记得:
正确缩进代码!使用四个空格.获得像Sublime Text 2这样知道如何处理缩进的编辑器.
尝试编写小(少于10行)函数并将它们链接在一起以制作完整的程序.这可以防止你在试图调试你想出的400行怪物时失去理智.
检查类型!例如,您可以加载ghci并键入:t read以查看read函数的类型.