简体   繁体   中英

Type constraints on typeclass instances in Haskell?

So I was playing around with Data.Set.Monad , which does not seem to be an instance of Data.Foldable like Data.Set is. I decided to try and add this instance myself as an experiment:

import Data.Foldable (Foldable, foldr)
import qualified Data.Set.Monad as S (Set, foldr)

instance Foldable S.Set where
  foldr = S.foldr

I get compilation error:

No instance for (Ord a) arising from a use of ‘S.foldr’
Possible fix:
  add (Ord a) to the context of
    the type signature for foldr :: (a -> b -> b) -> b -> Set a -> b
In the expression: S.foldr
In an equation for ‘foldr’: foldr = S.foldr
In the instance declaration for ‘Foldable Set’

Okay, this must be because S.foldr :: Ord a => (a -> b -> b) -> b -> Set a -> b . How do I express this constraint in the instance declaration? I tried this:

instance (Ord a) => Foldable (Set a) where
  foldr = S.foldr

And get another compilation error:

The first argument of ‘Foldable’ should have kind ‘* -> *’,
  but ‘Set a’ has kind ‘*’
In the instance declaration for ‘Foldable (Set a)’

What am I doing wrong? Or will Haskell even let me create this instance at all?

So, you need to define Foldable Set . Which means you can't depend on a , since foldr is required to work for any a .

So basically you would need constraint kinds to be embedded into the definition of Foldable to make this work, I think.

Note that Data.Set.foldr doesn't have the Ord a constraint so it can define a Foldable instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM