Haskell类型错误与where

use*_*183 5 haskell types

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)

Dan*_*zer 7

我们来看看它的类型 filter

filter :: (a -> Bool) -> [a]-> [a]
Run Code Online (Sandbox Code Playgroud)

类型niMatchNI -> 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)

更整洁,现在我们可以使用自动生成的吸气剂.