【问题标题】:Haskell Type error with whereHaskell 类型错误与 where
【发布时间】:2013-10-07 14:07:11
【问题描述】:
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

【问题讨论】:

  • 请包含Bank的定义。

标签: haskell types


【解决方案1】:

我们看看filter的类型

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

niMatch 的类型是NI -> Person -> Bool

所以 Haskell 将 aNI 统一起来,但 Person -> 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。

【讨论】:

    猜你喜欢
    • 2011-02-08
    • 2013-09-04
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    相关资源
    最近更新 更多