Skalla
Skalla

Reputation: 5

Haskell: Different in function declarations

I am writing the haversine formula in haskell. In one version of my function, the definition and declarations are as follows:

haversine :: Double -> Double -> Double -> Double -> Double
haversine lat1 lon1 lat2 lon2 = let dlon = (toRad lon2) - (toRad lon1)
                                    dlat = (toRad lat2) - (toRad lat1)
                                    a = sin(dlat/2)^2 + cos(lat1)*cos(lat2)*sin(dlon/2)^2
                                    c = 2 * asin(sqrt(a))
                                in c*r

This function compiles fine. When I change the declaration to:

haversine :: (Double a) => a -> a -> a -> a -> a

I get the following error:

• Expecting one fewer argument to ‘Double’
  Expected kind ‘* -> *’, but ‘Double’ has kind ‘*’
• In the type signature:
    haversine :: (Double a) -> a -> a -> a -> a -> a

To my knowledge, by writing (Double a), I am subjecting the rest of the parameters labeled 'a' to the Double type class constraint. Why does the latter declaration result in this error?

Upvotes: 0

Views: 102

Answers (2)

rampion
rampion

Reputation: 89043

1) Double a isn't a valid constraint. You're looking for Floating a

2) Constraints are given on the left hand side of a =>, unlike function arguments which are on the left hand side of a ->.

So to compile, your code should be

haversine :: Floating a => a -> a -> a -> a -> a
haversine lat1 lon1 lat2 lon2 = let dlon = (toRad lon2) - (toRad lon1)
                                    dlat = (toRad lat2) - (toRad lat1)
                                    a = sin(dlat/2)^2 + cos(lat1)*cos(lat2)*sin(dlon/2)^2
                                    c = 2 * asin(sqrt(a))
                                in c*r

Assuming you have globally defined

r :: Floating a => a
toRad :: Floating a => a -> a

Upvotes: 4

MathematicalOrchid
MathematicalOrchid

Reputation: 62808

In Haskell, a type and a class are two different things.

There is a type named Double.

There is no class named Double.

Also, a class constraint must be followed by =>, not ->.

You can constrain a variable by a class such as Eq, Show, etc. If you want it to be a specific type... well, just write that type instead of a variable.

Upvotes: 4

Related Questions