Retrieve an item from a list of tuples with more than two items (Haskell)

I am new to Haskell and need some help in this situation. I have the following list

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

My requirement is to get the amount corresponding to the account number, for example, for 001 it should give 100.

I wrote this function

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

The second line is where I got stuck in which the error message appears

  Syntax error in input (unexpected `| ') 

I would like to help. Thanx.

+4
source share
2 answers

Recall that Haskell type names begin with capital letters, so the type of checkBalance must be

 checkBalance :: AcInfo -> AcNo -> Amnt 

In your question, you seem to be aiming at using list comprehension, but you don't have the correct syntax.

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

This definition is great if the account is in dbase

  * Main> checkBalance bankAccounts "oo1"
 100 

but explodes when it is not.

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

The best type for checkBalance is

 checkBalance :: AcInfo -> AcNo -> Maybe Amnt 

to represent the general case, i.e. dbase may or may not contain number .

+6
source

In addition to Greg’s remark. I want to point out that you should not use tuples for large sets of values ​​that make up a logical unit. I would suggest an Account type, for example. using write syntax, which makes things like accessing items or changing an account more convenient:

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

See http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax for details.

Then you should write functions in terms of Account , not in terms of AcInfo , and use the usual list functions. Often the extractor functions provided by the record are good enough, as in your example:

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

Here acNo acc gets the account number, and amount acc gets the amount from the account.

+7
source

All Articles