The reason you can say “20 :: Double” is because in Haskell the integer literal is of type “Num a => a”, that is, it can be any number type that you like.
You are right that typeclass is a collection of types. To be precise, this is a set of types that implement functions in the "where" clause of the typeclass class. Your type signature for your numToDouble correctly expresses what you want to do.
, "n" , , Num. +, -, *, negate, abs, signum fromInteger. , , , .
, Num. numToDouble ? , , .
Real, , , , , , float, doubleles . "toRational", , Double, "fromRational", "Fractional".
, :
toDouble :: (Real n) => n -> Double
toDouble = fromRational . toRational
, , . GHCI :
Prelude> :type fromRational . toRational
fromRational . toRational :: (Fractional c, Real a) => a -> c
, ( , , , Real, Complex). , , .
:, leftaroundabout ,
realToFrac = fromRational . toRational