Haskell为Op声明Contravariant实例参数数量错误如何解决
错误原因
编译报错的核心是类型同义词(type synonym)的部分应用限制:
- Haskell 规定类型同义词必须被完全应用才能参与实例声明,即便开启
TypeSynonymInstances扩展也无法突破这个限制,该扩展仅支持为完全应用的类型同义词编写实例,不支持部分应用场景。 - 你之前给普通Functor编写实例时偏应用写法正常,是因为当时操作的是
data/newtype定义的自定义类型,而非type声明的类型同义词。
解决方案
方案1:将Op改为newtype定义(最推荐)
newtype支持部分应用,也是标准库实现Op的标准方式:
{-# LANGUAGE FlexibleInstances #-} module Type.Op where import Data.Functor.Contravariant ( Contravariant, contramap ) newtype Op r a = Op { getOp :: a -> r } instance Contravariant (Op r) where contramap f (Op g) = Op (g . f)
方案2:直接为原生函数类型写实例(仅作参考)
如果不需要自定义Op包装,也可以直接给函数类型写实例,注意该实现会和标准库同名实例冲突:
{-# LANGUAGE FlexibleInstances #-} import Data.Functor.Contravariant instance Contravariant ((->) r) where contramap f g = g . f
内容的提问来源于stack exchange,提问作者vkubicki
相关产品推荐
相关产品推荐

