2012-07-21 52 views
0

我希望用户进入元组的列表就可以了搜索键这样我可以说像这样继续输入元组

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) 

但它给我一个错误:

The last statement in do must be m <- getch 

我在做什么错?

+0

您是否尝试修理您的缩进? – fuz 2012-07-21 21:26:00

+0

首先,每个'if'必须有'else'子句。你最后的'if'没有。 – 2012-07-21 21:38:57

+0

好吧,我只是花了几分钟的时间来修复你的代码。我的结论是,此刻,这是一个完整的混乱。什么是“booker”,“bookFinding”和“enter”函数? – 2012-07-21 21:45:04

回答

5

它看起来像你正试图编写一个程序来读取书籍列表到某种数据库,然后搜索书籍。数据类型可以用来存储书籍信息:

data BookInfo = Book Int String [String] deriving (Show) 

现在让我们来看看您的函数,它从用户读取书籍信息。

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 

我搞掂你缩进你(这里有一个技巧:使用四个空格缩进),但也有其他的问题:

  • 线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]) 

现在将编译好的。注意我还添加了一个类型声明(这是可选的)。


您的下一个函数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) 

花点时间了解这个函数的工作原理。首先它会询问你是否有更多书籍可以进入。如果你说“N”,那么它返回空列表,然后你就完成了。否则,它会做一些神奇的事情 - 首先,它会调用getBookInfo来获取单本书的信息。然后它调用本身获取书籍列表!这是递归的一个例子。最后,它将第一本书添加到书籍列表中,并返回整个列表。


你现在应该自己写下剩下的程序。我可能会在一天左右重新访问这个答案以添加更多细节。如果您发表评论,让我知道您尝试了什么以及您卡在哪里,我更有可能这样做。请记住:

  • 正确缩进您的代码!使用四个空格。获取知道如何处理缩进的编辑器,如Sublime Text 2

  • 尝试编写小(少于10行)函数并将它们链接在一起以制作完整的程序。这将防止你在试图调试你所提出的400线怪物时失去理智。

  • 检查类型!您可以加载ghci并键入,例如,:t read可查看read函数的类型。

+0

谢谢你的帮助 – Malik 2012-07-21 23:32:51

+0

你不必使用四个空格来缩进;你只需要遵循越位规则。 – alternative 2012-07-22 11:53:19

+0

的确如此,但是当有人使用一个空格缩进,并且他们的一半问题来自不正确的缩进时,我认为告诉他们使用四个空格是有帮助的。 – 2012-07-22 11:58:10