从具有2个以上元素的元组列表中检索元素(Haskell)

时间:2011-07-04 02:42:57

标签: list haskell list-comprehension tuples nested-lists

我是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 `|')

我想对此有所帮助。感谢名单。

2 个答案:

答案 0 :(得分:7)

除了Greg的优秀答案之外,我想指出你不应该使用元组来构成构成逻辑单元的更大的值集。我建议使用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获取帐户中的金额。

答案 1 :(得分:6)

回想一下,Haskell类型的名称以大写字母开头,因此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