While solving the last exercise of this course, I realized that not only we can have
instance (Functor f, Contravariant g) => Contravariant (Compose f g) where
-- Implement the (>$<) function for a Contravariant instance for Compose
(>$<) :: (b -> a) -> Compose f g a -> Compose f g b
fun >$< Compose fga = Compose ((fun >$<) <$> fga)
but also
instance (Contravariant f, Functor g) => Contravariant (Compose f g) where
-- Implement the (>$<) function for a Contravariant instance for Compose
(>$<) :: (b -> a) -> Compose f g a -> Compose f g b
fun >$< Compose fga = Compose ((fun <$>) >$< fga)
The problem is that I cannot get the module to compile when I put both definitions. The error I get is
Duplicate instance declarations:
instance (Functor f, Contravariant g) =>
Contravariant (Compose f g)
-- Defined at /.../fp-course/src/Course/Compose.hs:62:10
instance (Contravariant f, Functor g) =>
Contravariant (Compose f g)
-- Defined at /.../fp-course/src/Course/Compose.hs:71:10
|
62 | instance (Functor f, Contravariant g) =>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
and I couldn't manage to get rid of it by adding the deprecated extension {-# LANGUAGE OverlappingInstances #-} or the {-# OVERLAPPABLE #-}/{-# OVERLAPPING #-}/{-# OVERLAPS #-} pragmas as explained here.
Is there a way to have both definitions in the module?
Edit: sorry I forgot to mention that the course redefines custom type classes Functor, Contravariant, etc... (>$<) corresponds to contramap.