I've got a question about type classes. I've got the following code:
import Foreign.C.Types (CDouble, CFloat)
class Floating a => Trigonometry a where
versin :: a -> a
versin x = 1 - cos x
vercos :: a -> a
vercos x = 1 + cos x
coversin :: a -> a
coversin x = 1 - sin x
covercos :: a -> a
covercos x = 1 + sin x
haversin :: a -> a
haversin x = versin x * 0.5
havercos :: a -> a
havercos x = vercos x * 0.5
hacoversin :: a -> a
hacoversin x = coversin x * 0.5
hacovercos :: a -> a
hacovercos x = covercos x * 0.5
instance Trigonometry CDouble
instance Trigonometry CFloat
instance Trigonometry Double
instance Trigonometry Float
Now my question is: there can be infinite amount of Floating instances, and obviously every single instance of Floating can be an instance of Trigonometry without extra implementation. Is there a way to avoid the explicit instance declarations at the bottom and automatically make all Floating instances become Trigonometry instance too?
Cheers!
For this case, there is probably no need to define a typeclass at all, you can implement these functions as top level functions with a Floating type constraint:
versin :: Floating a => a -> a
versin x = 1 - cos x
vercos :: Floating a => a -> a
vercos x = 1 + cos x
coversin :: Floating a => a -> a
coversin x = 1 - sin x
covercos :: Floating a => a -> a
covercos x = 1 + sin x
haversin :: Floating a => a -> a
haversin x = versin x * 0.5
havercos :: Floating a => a -> a
havercos x = vercos x * 0.5
hacoversin :: Floating a => a -> a
hacoversin x = coversin x * 0.5
hacovercos :: Floating a => a -> a
hacovercos x = covercos x * 0.5
If you want to make a special implementation for a certain Floating type, you can indeed work with a typeclass, but if you implement an instance Floating a => Trigonometry a, you likely will end up with overlapping instances.
For those who are looking for something similar, I figured it out:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Algorithms.Math.Trigonometry where
class Floating a => Trigonometry a where
versin :: a -> a
versin x = 1 - cos x
vercos :: a -> a
vercos x = 1 + cos x
coversin :: a -> a
coversin x = 1 - sin x
covercos :: a -> a
covercos x = 1 + sin x
haversin :: a -> a
haversin x = versin x * 0.5
havercos :: a -> a
havercos x = vercos x * 0.5
hacoversin :: a -> a
hacoversin x = coversin x * 0.5
hacovercos :: a -> a
hacovercos x = covercos x * 0.5
instance Floating a => Trigonometry a
Language extension magic :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With