继续进入元组

0 io haskell syntax-error

我希望用户输入一个元组列表,在其上搜索一个像这样的密钥,我可以这样说

  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)

我究竟做错了什么?

Chr*_*lor 5

看起来你正在尝试编写一个程序来将书籍列表读入某种数据库,然后搜索书籍.您可以从存储书信息的数据类型开始:

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函数的类型.