Экземпляр
instance (Num t) => Mul t t t where
(*) = ??
Во многом победит цель определения Mul t t t
во-первых, без злоупотребления расширениями для разрешения {-# LANGUAGE OverlappingInstances #-}
.
К сожалению, «правильный», если болезненный ответ, - это пройти экземпляр за экземпляром и сделать
import Prelude hiding ((*))
import qualified Prelude
instance Mul Int Int Int where
(*) = (Prelude.*)
instance Mul Double Double Double where
(*) = (Prelude.*)
instance Mul Int Double Double where
...
instance Mul (Complex Float) (Complex Double) (Complex Double)
...
В противном случае способ, которым головки экземпляров разрешаются в компиляторе (обратного отслеживания не производится), вероятно, приведет к тому, что ваши новые экземпляры приведут к взрыву компиляции, когда вы действительно их используете.
Тем не менее, вы можете, по крайней мере, облегчить боль в случаях, о которых вы не задумывались:
newtype Other a = Other a
instance Num a => Mul (Other a) (Other a) (Other a) where
Other a * Other b = Other (a Prelude.* b)
Это, по крайней мере, позволит им просто использовать вашу обертку нового типа, если они не хотят идти и определять Mul и все остальные ваши классы сами.