仅在类型构造函数上多态的实例有什么意义?

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

{-# LANGUAGE FlexibleInstances, FlexibleContexts #-}

在Haskell中我可以做类似

的事情
class C a where
  c :: a -> a

instance C (f Integer) where
  c = id

正如所见,C 的实例是多态的,但仅在类型构造函数上而不是在类型参数上。这个功能有什么意义?我从未见过它被使用过,但由于它是允许的,我假设在某些情况下它是有用的。是吗?

你已经看到它被使用了。下面是一些示例:

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)

其中每一个都是箭头类型的多态——分别是 mf 以及 ft。如果您 必须 在实例头中看到它,那么将其中任何一个提升到类似实例并不难。例如:

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

作为术语说明:“类型构造函数”实际上并不是“带箭头类型的类型”的同义词,原因与“数据构造函数”与“带箭头类型的值”不是同义词的原因基本相同。

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