Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 741
Tim Perry Avatar asked May 25 '11 03:05

Tim Perry


People also ask

What is an overloaded function in Haskell?

A symbol is overloaded if it has two (or more) meanings, distinguished by type, that are resolved at compile time. For example, in Haskell, as in many other languages, the operator + has (at least) two distinct implementations associated with it, one of type Int -> Int -> Int, the other of type Float -> Float -> Float.

What is signature in function overloading?

Function SignatureA function's signature includes the function's name and the number, order and type of its formal parameters. Two overloaded functions must not have the same signature. The return value is not part of a function's signature.

Can you overload in Haskell?

Overloading in Haskell is only available using type classes. In this case, (+) belongs to the Num type class, so you would have to provide a Num instance for your type.


1 Answers

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.

like image 76
sclv Avatar answered Sep 20 '22 04:09

sclv