我对在 Haskell 中使用 foldl 的类型定义有疑问,我有以下类型:
data Client = GovOrg String
| Company String Integer Person String
| Individual Person Bool
deriving Show
data Person = Person String String Gender
deriving Show
data Gender = Male | Female | Unknown
deriving (Show, Eq, Ord)
data GenderStat = GenderStat Gender Integer deriving Show
foldl 使用以下函数定义:
clientGender :: Client -> Gender
clientGender client = case client of
Company _ _ (Person _ _ gender) _ -> gender
Individual (Person _ _ gender) _ -> gender
_ -> Unknown
incrementGenderStat :: GenderStat -> GenderStat
incrementGenderStat (GenderStat gender num) = GenderStat gender (num + 1)
genderStats:: [GenderStat] -> Client -> [GenderStat]
genderStats [maleStat, femaleStat, unknownStat] client = case clientGender client of
Male -> [incrementGenderStat maleStat, femaleStat, unknownStat]
Female -> [maleStat, incrementGenderStat femaleStat, unknownStat]
Unknown -> [maleStat, femaleStat, incrementGenderStat unknownStat]
-- genderStatsOfClients :: Client a ->
genderStatsOfClients = foldl genderStats [GenderStat Male 0, GenderStat Female 0, GenderStat Unknown 0]
当我尝试将我的模块加载到ghci
中时,它会引发错误:
• Ambiguous type variable ‘t0’ arising from a use of ‘foldl’ │
prevents the constraint ‘(Foldable t0)’ from being solved. │
Relevant bindings include │
genderStatsOfClients :: t0 Client -> [GenderStat] │
(bound at src/Section2/DataTypes.hs:82:1) │
Probable fix: use a type annotation to specify what ‘t0’ should be. │
These potential instances exist: │
instance Foldable (Either a) -- Defined in ‘Data.Foldable’ │
instance Foldable Maybe -- Defined in ‘Data.Foldable’ │
instance Foldable ((,) a) -- Defined in ‘Data.Foldable’ │
...plus one other │
...plus 22 instances involving out-of-scope types │
(use -fprint-potential-instances to see them all) │
• In the expression: │
foldl │
genderStats │
[GenderStat Male 0, GenderStat Female 0, GenderStat Unknown 0] │
In an equation for ‘genderStatsOfClients’: │
genderStatsOfClients │
= foldl │
genderStats │
[GenderStat Male 0, GenderStat Female 0, GenderStat Unknown 0] │
Failed, modules loaded: none.
我试图通过按照建议为函数提供类型注释来纠正这个问题:
-- genderStatsOfClients :: Foldable Client => ([GenderStat] -> a -> [GenderStat]) -> [GenderStat] -> [a] -> [GenderStat]
我想知道如何在这里提供适当的类型约束,如果我使用Foldable Client a
,它表示它期望Foldable
.
我也尝试过类型定义:
genderStatsOfClients :: (Foldable f, Client a) => ([GenderStat] -> (f a) -> [GenderStat]) -> [GenderStat] -> [(f a)] -> [GenderStat]
genderStatsOfClients = foldl genderStats [GenderStat Male 0, GenderStat Female 0, GenderStat Unknown 0]
引发错误:
src/Section2/DataTypes.hs:81:38: error: │
• Expecting one fewer argument to ‘Client’ │
Expected kind ‘* -> Constraint’, but ‘Client’ has kind ‘*’ │
• In the type signature: │
genderStatsOfClients :: (Foldable f, Client a) => │
([GenderStat] -> (f a) -> [GenderStat]) │
-> [GenderStat] -> [(f a)] -> [GenderStat]