Type signature of num to double?
haskell, type-conversion
Solution
The reason you can say "20::Double" is that in Haskell an integer literal has type "Num a => a", meaning it can be any numeric type you like.
You are correct that a typeclass is a set of types. To be precise, it is the set of types that implement the functions in the "where" clause of the typeclass. Your type signature for your numToDouble correctly expresses what you want to do.
All you know about a value of type "n" in your function is that it implements the Num interface. This consists of +, -, *, negate, abs, signum and fromInteger. The last is the only one that does type conversion, but its not any use for what you want.
Bear in mind that Complex is also an instance of Num. What should numToDouble do with that? The Right Thing is not obvious, which is part of the reason you are having problems.
However lower down the type hierarchy you have the Real typeclass, which has instances for all the more straightforward numerical types you probably want to work with, like floats, doubles and the various types of integers. That includes a function "toRational" which converts any real value into a ratio, from which you can convert it to a Double using "fromRational", which is a function of the "Fractional" typeclass.
So try:
toDouble :: (Real n) => n -> Double
toDouble = fromRational . toRational
But of course this is actually too specific. GHCI says:
Prelude> :type fromRational . toRational
fromRational . toRational :: (Fractional c, Real a) => a -> c
So it converts any real type to any Fractional type (the latter covers anything that can do division, including things that are not instances of Real, like Complex) When messing around with numeric types I keep finding myself using it as a kind of generic numerical coercion.
Edit: as leftaroundabout says,
realToFrac = fromRational . toRational
Problem
I'm just starting Learn You a Haskell for Great Good, and I'm having a bit of trouble with type classes. I would like to create a function that takes any number type and forces it to be a double. My first thought was to define ``` numToDouble :: Num -> Double ``` But I don't think that worked because `Num` isn't a type, it's a typeclass (which seems to me to be a set of types). So looking at `read`, shows `(Read a) => String -> a`. I'm reading that as "read takes a string, and returns a thing of type `a` which is specified by the user". So I wrote the following ``` numToDouble :: (Num n) => n -> Double numToDouble i = ((i) :: Double) ``` Which looks to me like "take thing of type n (must be in the `Num` typeclass, and convert it to a Double". This seems reasonable becuase I can do `20::Double` This produces the following output ``` Could not deduce (n ~ Double) from the context (Num n) bound by the type signature for numToDouble :: Num n => n -> Double ``` I have no idea what I'm reading. Based on what I can find, it seems like this has something to do with polymorphism? Edit: To be clear, my question is: Why isn't this working?