У меня есть трехмерный векторный тип данных, определенный как 3 поплавки. Я понимаю, что если я предоставляю экземпляр Num
для своего класса и определяю нормальные математические операторы, я могу использовать их в своем классе.Зачем нужна сумма GHC.Num.fromInteger?
data Vec3 = Vec3 { x :: Float
, y :: Float
, z :: Float
} deriving (Show, Eq)
instance Num Vec3 where
(+) v1 v2 = Vec3 (x v1 + x v2) (y v1 + y v2) (z v1 + z v2)
Когда я загружаю свой файл в GHCI, я получаю предупреждение, потому что я не определить все функции в Num
, что имеет смысл.
Prelude> :l temp.hs
[1 of 1] Compiling Main (temp.hs, interpreted)
temp.hs:6:10: Warning:
No explicit method or default declaration for `*'
In the instance declaration for `Num Vec3'
temp.hs:6:10: Warning:
No explicit method or default declaration for `abs'
In the instance declaration for `Num Vec3'
temp.hs:6:10: Warning:
No explicit method or default declaration for `signum'
In the instance declaration for `Num Vec3'
temp.hs:6:10: Warning:
No explicit method or default declaration for `fromInteger'
In the instance declaration for `Num Vec3'
Ok, modules loaded: Main.
Однако я все еще могу использовать те, которые я определил.
*Main> let a = Vec3 1.0 2.0 3.0
*Main> let b = Vec3 2.0 4.0 5.0
*Main> a + b
Vec3 {x = 3.0, y = 6.0, z = 8.0}
Моя путаница происходит из-за ошибки, я получаю при попытке использовать функцию суммы
*Main> sum [a,b]
Vec3 {x = *** Exception: temp.hs:6:10-17: No instance nor default method for class operation GHC.Num.fromInteger
Почему нужна сумма в fromInteger
определение для моего типа данных Vec3
? Во-первых, я бы предположил, что сумма использует только функцию +
, а для другого мой тип данных не использует Integer
.
Вы должны всегда определять ** все ** операции в минимальном полном определении, прежде чем рассматривать тип данных как экземпляр класса ... – Bakuriu
Настоящая проблема заключается в том, что вы создаете 'Vec3' экземпляр' Num', хотя векторы не являются числами. – rightfold
Чтобы расширить на @rightfold - не делайте что-то экземпляр Num только потому, что вы хотите + - векторы не являются числами, даже если некоторые из операторов, которые вы используете на векторах, имеют то же имя, что и числовые операторы. (хотя вы _can_ рассматриваете векторы как числа, если по «вектору» вы просто означаете «набор чисел с фиксированным размером» вместо вектора в геометрическом или физическом смысле). – Cubic