Mam 3d typ danych wektorowych zdefiniowany jako 3 pływaki. Rozumiem, że jeśli udostępnię instancję Num
dla mojej klasy i zdefiniuję normalne operatory matematyczne, będę mógł użyć ich na mojej klasie.dlaczego suma potrzebuje 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)
Kiedy załadować mój plik do ghci, dostaję ostrzeżenia, bo nie określają wszystkich funkcji Num
, które ma sens.
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.
Jednak nadal mogę używać tych, które zdefiniowałem.
*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}
Moja dezorientacja pochodzi z następującym błąd pojawia się podczas próby użycia funkcji sumy
*Main> sum [a,b]
Vec3 {x = *** Exception: temp.hs:6:10-17: No instance nor default method for class operation GHC.Num.fromInteger
Dlaczego suma potrzebują fromInteger
definicję dla mojego Vec3
typu danych? Po pierwsze, doszedłem do wniosku, że suma korzysta tylko z funkcji +
, a po drugie, mój typ danych nie używa Integer
.
Powinieneś zawsze zdefiniować ** wszystkie ** operacji w minimalnej kompletnej definicji, zanim uznasz typ danych za instancję klasy ... – Bakuriu
Prawdziwy problem polega na tym, że tworzysz 'Vec3' instancję' Num', chociaż wektory nie są liczbami. – rightfold
Aby rozwinąć na @rightfold - nie rób czegoś z Num tylko dlatego, że chcesz + - wektory nie są liczbami, nawet jeśli niektóre z operatorów, których używasz na wektorach, mają zwykle taką samą nazwę jak operatory liczb. (chociaż możesz traktować wektory jako liczby, jeśli przez "wektor" oznacza się po prostu "zbiór o stałej wielkości liczb" zamiast wektora w sensie geometrycznym lub fizycznym). – Cubic