Home > Mobile >  What's the point of instances polymorphic only on type constructors?
What's the point of instances polymorphic only on type constructors?

Time:12-01

{-# LANGUAGE FlexibleInstances, FlexibleContexts #-}

In Haskell I can do something like

class C a where
  c :: a -> a

instance C (f Integer) where
  c = id

As seen, the instance of C is polymorphic, but only on the type constructor and not on the type parameter. What is the point of this feature? I have never seen this used, but since it is allowed I assume there is some case where it is useful. Is it?

CodePudding user response:

You've seen it used. Here's some examples:

return :: Monad m => a -> m a
and :: Foldable f => f Bool -> Bool
traverse :: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)

Each of these is polymorphic in a type with arrow kind -- respectively, m, f, and both f and t. If you must see it in an instance head, it's not hard to lift any of these to an analogous instance. For example:

class Bullish a where bull :: a -> Bool
instance Bullish Bool where bull = id
instance Bullish Int where bull = (0/=)
instance Foldable f => Bullish (f Bool) where bull = and

As a terminology note: "type constructor" is not actually synonymous with "type with arrow kind", for essentially the same reasons that "data constructor" is not synonymous with "value with arrow type".

                   arrow kind    not arrow kind
constructor        Maybe         Bool
not constructor    State Int     Maybe Char
  • Related