ContrainedなFunctorを実装していて直面した問題です
問題の本質を以下の単純化したコードで例示します
最後2つのインスタンス宣言の間で"Duplicate instance declarations" エラーが発生してしまいます
これは型aがOldAとUsefulFoo両方のクラスのインスタンスである場合どちらのnewHogeを実行すればいいのか区別がつかないからですが
実用上このケースは無意味で意図してコードを書かなければ起こり得ません
OldAとUsefulFooの両方のインスタンスになるような型が存在しないことをghcに伝えられればエラーにしなくても良いと思うのですがそのようなテクニックや言語拡張はあるのでしょうか

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}

class OldA a where
hoge :: a -> a

class NewA a where
newHoge :: a -> a

class UsefulFoo a where
us :: a -> a
ef :: a -> a
ul :: a -> a

instance OldA a => NewA a where
newHoge = hoge

instance UsefulFoo a => NewA a where
newHoge = us . ef . ul