4

我是 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}

第二行是我卡在它给出错误消息的地方

输入中的语法错误(意外的“|”)

我想在这方面得到一些帮助。谢谢。

4

2 回答 2

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从帐户中获取金额。

于 2011-07-04T07:12:57.927 回答
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"
*** 例外:Prelude.head:空列表

更好的类型checkBalance

checkBalance :: AcInfo -> AcNo -> Maybe Amnt

代表一般情况,dbase可能包含也可能不包含number

于 2011-07-04T03:10:38.783 回答