5
type NI = Int
type Age = Int
type Balance = Int
type Person = (NI, Age, Balance) 
type Bank = [Person]


sumAllAccounts :: NI -> Bank -> Int
sumAllAccounts n l = filter niMatch l
    where niMatch n (a,_,_) 
        | n == a    =   True
        | otherwise =   False

当我运行这个函数时,我得到一个类型错误

couldnt match type (Person, t0, t1) -> Bool with Bool

但是,当我让 where 成为它自己的功能时,它可以工作

personNIMatchs :: NI -> Person -> Bool
personNIMatchs n (a,_,_) 
    | n == a    =   True
    | otherwise =   False
4

1 回答 1

7

我们来看看类型filter

filter :: (a -> Bool) -> [a]-> [a]

的类型niMatchNI -> Person -> Bool

所以 Haskell 与 结合aNIPerson -> Bool不起作用!那不是Bool,因此您的错误消息有些令人困惑。从视觉上看,Haskell 是统一的

   a   -> Bool
-- ^      ^ unification error!
   NI  -> (Person -> Bool) 

现在我假设type Bank = [Person]你只是想要

 sumAllAccounts n = sum . map getBalance . filter matchNI
   where matchNI (a, _, _) = a == n
         getBalance (_, _, b) = b
 -- I've added the code here to actually sum the balances here
 -- without it, you're returning a Bank of all a persons accounts.

但我们可以做得更好!让我们使用更惯用的 Haskell 方法并将其存储Person为记录。

newtype Person = Person {
  ni :: NI,
  age :: Age,
  balance :: Balance
} deriving (Eq, Show)

sumAllAccounts :: NI -> Bank -> Balance
sumAllAccounts n = sum . map balance . filter ((==n) . ni)

更整洁,现在我们可以使用自动生成的 getter。

于 2013-10-07T05:37:00.577 回答