2012-07-21 67 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