Я определяю свой собственный тип данных с числовыми числами как упражнение для обучения, и я столкнулся с проблемой перегрузки abs
вместе с другими членами Num
. Насколько я знаю, только одно определение экземпляра допускается на класс типов, но если бы я мог, я бы сделал что-то вроде этого:Различные ограничения типа для одного и того же экземпляра
instance Num a => Num (Complex a) where
(+) (Complex ra ia) (Complex rb ib) = Complex (ra + rb) (ia + ib)
(-) (Complex ra ia) (Complex rb ib) = Complex (ra - rb) (ia - ib)
(*) (Complex ra ia) (Complex rb ib) = Complex (ra*rb - ia*ib) (ra*ib + rb*ia)
fromInteger r = Complex (fromInteger r) 0
instance Floating a => Num (Complex a) where
abs (Complex r i) = Complex (sqrt $ r^2 + i^2) 0
или
instance Floating a => Floating (Complex a) where
abs (Complex r i) = Complex (sqrt $ r^2 + i^2) 0
Потому что ни один из отличных abs
членов требуют Floating
типов, и я не хочу ограничивать их только Floating
типами, но функция abs
очень важна, и я не хочу излишне исключать ее.
Есть ли способ, которым я могу иметь функции (+)
, (-)
и (*)
работать со всеми числовыми типами, сохраняя при этом abs
?
Согласно 7.6.3.4. Overlapping instances в руководстве системы GHC, несколько экземпляров могут перекрываться, если они отличаются от типа ограничения (?) Вне контекста (например, instance C [a]
и instance C [Int]
), с компилятором выбирая наиболее конкретный экземпляр для данного случая , но в нем ничего не говорится о различии только контекста (например, instance C [a]
и instance Integral a => C [a]
).
К сожалению, иерархия типов для «чисел» (или «базовая алгебра» или что-то, что ее следует назвать) была довольно плохо продумана с самого начала. Может быть, вам лучше обойти это полностью для вашего «комплекса а»? Существует [альтернативная иерархия] (https://hackage.haskell.org/package/numeric-prelude), но это может быть немного переполнено для вашей ситуации. Сказанное по-разному: вам, похоже, нужен принципиальный способ создания классного ряда для сложных чисел. Стандартные типы типов, такие как 'Num', с которыми вы хотите работать, очень ad-hoc :-( – gspr
@gspr: иерархия чисел может быть не оптимальной, но на практике она работает очень хорошо. Что касается этого варианта использования - почти во всех реальных приложениях комплексных чисел вам понадобится «Floating» в любом случае, сложные числа в основном полезны в контексте корней и/или экспонент (для описания колебаний). – leftaroundabout
@leftaroundabout: Согласен, хотя можно было бы представить практический и полезный экземпляр для «Ratio Integer». – gspr