2011-07-04 177 views
4

我是Haskell的新手,在這種情況下需要一些幫助。我有以下列表從超過2個元素的元組列表中檢索元素(Haskell)

-- create a type for bank account 
type AcNo = String 
type Name = String 
type City = String 
type Amnt = Int 

type AcInfo = [(AcNo, Name, City, Amnt)] 

-- function to get the data of bank accounts to a list of tuples 
bankAccounts :: AcInfo 
bankAccounts = [("oo1", "Sahan", "Colomb", 100),("002", "John", "Jafna", 200)] 

我的要求是獲得對應賬號的金額,例如,對於001它應該給100

我寫的功能是這樣的

--Function to check the balance of a person 
checkBalance :: bankAccounts -> AcNo -> Amnt 
checkBalance dbase number = Amnt|(AcNo, Name, City, Amnt) <- dbase, AcNo==number} 

第二行是我卡在哪裏給出錯誤信息

Syntax error in input (unexpected `|')

我想對此有所幫助。感謝名單。

回答

6

回想一下,哈斯克爾類型的名稱以大寫字母,所以checkBalance類型應該是

checkBalance :: AcInfo -> AcNo -> Amnt 

在你的問題,你似乎瞄準使用列表理解,但是你沒有語法非常正確。

checkBalance dbase number = head [amnt | (acNo, name, city, amnt) <- dbase, 
             acNo == number] 

這個定義是好的,如果一個帳戶是dbase

*Main> checkBalance bankAccounts "oo1" 
100

但炸燬當它不是。

*Main> checkBalance bankAccounts "001" 
*** Exception: Prelude.head: empty list

checkBalance更好的類型是

checkBalance :: AcInfo -> AcNo -> Maybe Amnt 

來表示一般情況下,即dbase可以或可以不包含number

+0

非常感謝您提供的幫助。是的。目前我只專注於dbase中的賬戶。我將試驗你提到的類型。再次感謝。 –

7

格雷格的優秀答案的補充我想指出,你不應該使用元組來構成一個邏輯單元的更大的值集合。我建議有一個Account類型,例如使用記錄語法,這使得事情一樣訪問元素或修改帳戶,更方便:

data Account = Account { acNo :: AcNo 
         , name :: Name 
         , city :: City 
         , amount :: Amnt 
         } deriving (Eq, Show) 

詳見http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax

然後,您應該按照Account而不是按照AcInfo編寫函數,並使用正常列表函數。通常由記錄中的提取功能足夠好,因爲在你的榜樣:

checkBalance :: [Account] -> AcNo -> Maybe Amnt 
checkBalance dbase number = fmap amount $ find (\acc -> number == acNo acc) dbase 

這裏acNo acc獲取賬號和amount acc從一個賬戶的金額。

相關問題