2011-07-04 132 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从一个账户的金额。

相关问题