There is a function fromIntegral that converts an integer to any other numeric type. So you can do:
result :: (Integral n, Num m) => n -> m -> m result val coefficient = fromIntegral val * coefficient
Or, in a dotless style:
result = (*) . fromIntegral
Update Updated Question (@Drew)
Consider this code:
coefficient :: (Num a) => a coefficient = 1.0
This is not true for him, as shown below. Since 1.0 is a literal for a fractional number (and not an integer), the GHC can only encode it as any type that can represent fractional numbers (forall a. Fractional a => a). However, you indicated that it must be valid for any number type (forall a. Num a => a). Some numeric types (e.g. Integer) cannot represent fractional values ββand are not Fractional instances (rightly so), so this cannot be checked by typecheck. You can fix it as follows:
coefficient :: (Fractional a) => a coefficient = 2.0
Here the GHC can infer the type, and the coefficient works fine. It is important to note that Fractional is a subclass of Num, so everything that is Fractional should also be Num. If we look at the function in the first part of my answer, then the coefficient should be only the Num type (since we use it only with (*)), so we can use this definition of the coefficient instead of this parameter. Your problem arises for the same reason.
result :: (Num a) => a result = coefficient * fromIntegral val
Again, the result of this function should be of the same type as the coefficient. Since the coefficient cannot be any type of Num, but only a fractional type, we need to change it to:
result :: (Fractional a) => a result = coefficient * fromIntegral val
And then it should be checked. @singpolyma is right that your original mistake was partially related to monomorphism restriction, but you just had to make type signatures a bit more specific. If you want it to work with (Num a) => a, then the coefficient should be an integer (e.g. 1).
GHCi Update (@Marcin)
To use this in GHCi, I would suggest letting GHCi infer a type. If in this case you enter (in GHCi):
let result val coefficient = fromIntegral val * coefficient
Then GHCi will correctly infer the type of result. You can ask GHCi what type it thinks that something uses the ": t" command:
Prelude> :t result result :: (Integral a1, Num a) => a1 -> a -> a
If you must have an explicit type signature, you can do:
let result = (\val coefficient -> fromIntegral val * coefficient) :: (Integral a, Num b) => a -> b -> b
To try to get an explicit type, but GHCi will make it monomorphic:
Prelude> :t result result :: Integer -> Integer -> Integer
What we do not want (this is because the type annotation refers to the value of the lambda expression, and not to the declaration of the result). I donβt know how to get an explicit type to work here, so maybe someone more knowledgeable than us might answer: P