Home > Mobile >  Haskell - typeclass extension
Haskell - typeclass extension

Time:01-26

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!

CodePudding user response:

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 :)

CodePudding user response:

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.

  •  Tags:  
  • Related