Давайте посмотрим на тип реализации, который вам нужно будет предоставить для (.*.)
, чтобы Wrap
стал экземпляром MixedRing
. Подстановка Wrap
для b
в типе метода дает
(.*.) :: Num a => Wrap -> a -> Wrap
Поскольку Wrap
изоморфно Int
и не нужно думать о переносе и развертывании с Wrap
и get
, давайте сведем нашу цель к поиску реализации
(.*.) :: Num a => Int -> a -> Int
(Вы видите, что это не делает задачу легче или сложнее, не так ли?)
Теперь обратите внимание, что такая реализация должна иметь возможность работать со всеми типами a
, которые находятся в классе типов Num
. (Это то, что переменная типа в таком типе обозначает: универсальная квантификация.) Примечание: это не то же самое (на самом деле, это наоборот), когда говорят, что ваша реализация сама может выбирать, над чем a
работать); тем не менее это то, что вы, похоже, предлагаете в своем вопросе: чтобы вашей реализации было разрешено выбрать Int
в качестве выбора для a
.
Теперь, когда вы хотите реализовать этот конкретный (.*.)
в терминах (*)
для значений типа Int
, нам нужно что-то вида
n .*. s = n * f s
с
f :: Num a => a -> Int
Я не могу представить себе функцию, которая преобразует из произвольного Num
-типа a
в Int
осмысленным образом. Поэтому я бы сказал, что нет никакого осмысленного способа сделать Int
(и, следовательно, Wrap
) экземпляром MixedRing
; то есть не так, что экземпляр ведет себя так, как вы, вероятно, ожидаете.