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
Run Code Online (Sandbox Code Playgroud)
当我运行此功能时,我得到一个类型错误
couldnt match type (Person, t0, t1) -> Bool with Bool
Run Code Online (Sandbox Code Playgroud)
但是当我把它自己的功能放在哪里时它起作用
personNIMatchs :: NI -> Person -> Bool
personNIMatchs n (a,_,_)
| n == a = True
| otherwise = False
Run Code Online (Sandbox Code Playgroud)
我们来看看它的类型 filter
filter :: (a -> Bool) -> [a]-> [a]
Run Code Online (Sandbox Code Playgroud)
类型niMatch
是NI -> Person -> Bool
因此,哈斯克尔统一a
使用NI
,但Person -> Bool
不能正常工作!这不是一个Bool
,因此你有点混乱的错误信息.在视觉上看到这个Haskell正在统一
a -> Bool
-- ^ ^ unification error!
NI -> (Person -> Bool)
Run Code Online (Sandbox Code Playgroud)
现在我假设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.
Run Code Online (Sandbox Code Playgroud)
但我们可以做得更好!让我们做更惯用的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)
Run Code Online (Sandbox Code Playgroud)
更整洁,现在我们可以使用自动生成的吸气剂.