Search code examples
haskelltype-signature

Overloading function signatures haskell


I get the following error message when I compile:

Duplicate type signature:
weightedMedian.hs:71:0-39: findVal :: [ValPair] -> Double -> Double
weightedMedian.hs:68:0-36: findVal :: [ValPair] -> Int -> Double

My solution is to have findValI and findValD. However, findValI just converts the Int type to a Double and calls findValD.

Also I can't pattern match on types of Num (Int, Double) so I can't just change the type signature to

findVal :: [ValPair] -> Num -> Double   

In many languages I wouldn't need different names. Why do I need different names in Haskell? Would this be hard to add to the language? Or are there dragons there?


Solution

  • Ad-hoc polymorphism (and name overloading) are provided in Haskell by typeclasses:

    class CanFindVal a where
              findVal :: [ValPair] -> a -> Double
    
    instance CanFindVal Double where
         findVal xs d = ...
    
    instance CanFindVal Int where
         findVal xs d = findVal xs (fromIntegral d :: Double)
    

    Note that in this case, since findVal "really" needs a Double, I'd just always have it take a double, and when I needed to pass it an int, just use fromIntegral at the call site. You generally want typeclasses when there's actually different behavior or logic involved, rather than promiscuously.