Reputation: 43
I'm new to Haskell and need some help on 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, e.g., for 001 it should give 100.
The function I wrote was this
--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 im stuck at which gives the error message
Syntax error in input (unexpected `|')
I'd like to have some help on this. Thanx.
Upvotes: 4
Views: 858
Reputation: 54574
Additional to Greg's excellent answer I want to point out that you shouldn't use tuples for bigger sets of values that constitute a logical unit. I would suggest to have an Account
type, e.g. using record syntax, which makes things like accessing elements or making account changes 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 normal 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 an account.
Upvotes: 7
Reputation: 139441
Recall that names of Haskell types begin with capital letters, so the type of checkBalance
should be
checkBalance :: AcInfo -> AcNo -> Amnt
In your question, you seem to aim at using a list comprehension, but you don't have the syntax quite right.
checkBalance dbase number = head [amnt | (acNo, name, city, amnt) <- dbase,
acNo == number]
This definition is fine if an account is in dbase
*Main> checkBalance bankAccounts "oo1" 100
but blows up when it isn't.
*Main> checkBalance bankAccounts "001" *** Exception: Prelude.head: empty list
A better type for checkBalance
is
checkBalance :: AcInfo -> AcNo -> Maybe Amnt
to represent the general case, i.e., dbase
may or may not contain number
.
Upvotes: 6