Mind this program:
class Convert a b where
convert :: a -> b
data A = A deriving Show
data B = B deriving Show
data C = C deriving Show
data D = DA A | D
For that code to work, it would have to work with any argument of the same type. That is, if
get (DB B) :: A
works then
get anyValueOfTypeD :: A
has to work, including
get (DC C) :: A
which can not work because of a missing instance from C to A.
The first line
get anyValueOfTypeD :: B
works because we do have all the three instances to convert A,B,C to B.
I do not think there's any workaround that allows you to leave the type D
as it is. If instead you can change that, you could use e.g.
data D a = DA a | DB a | DC a
(mind that it's quite different from the original), or even the GADT
data D x where
DA :: A -> D A
DB :: B -> D B
DC :: C -> D C