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
When I run this function i get a type error
couldnt match type (Person, t0, t1) -> Bool with Bool
However when I make the where its own function it works
personNIMatchs :: NI -> Person -> Bool
personNIMatchs n (a,_,_)
| n == a = True
| otherwise = False
Let's look at the type of filter
filter :: (a -> Bool) -> [a]-> [a]
The type of niMatch
is NI -> Person -> Bool
So Haskell unifies a
with NI
, but Person -> Bool
doesn't work! That's not a Bool
, hence your somewhat confusing error message. To see this visually Haskell is unifying
a -> Bool
-- ^ ^ unification error!
NI -> (Person -> Bool)
Now I assume that type Bank = [Person]
then you just want
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.
But we can make this better! Let's do the more idiomatic Haskell approach and store Person
as a record.
newtype Person = Person {
ni :: NI,
age :: Age,
balance :: Balance
} deriving (Eq, Show)
sumAllAccounts :: NI -> Bank -> Balance
sumAllAccounts n = sum . map balance . filter ((==n) . ni)
Much neater, now we can use the autogenerated getters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With