Consider the following excerpt from GHCI:
Prelude> :t sum [1,2,3]
sum [1,2,3] :: Num a => a
Prelude> :t fromIntegral (length [1,2,3])
fromIntegral (length [1,2,3]) :: Num b => b
Prelude> :t sum [1,2,3] / fromIntegral (length [1,2,3])
sum [1,2,3] / fromIntegral (length [1,2,3]) :: Fractional a => a
I understand that both sum [1,2,3]
and fromIntegral (length [1,2,3])
are instances of Num
. What puzzles me is, why does the compiler convert the operands to Fractional
? I thought that numeric conversions had to be explicit in Haskell.
Thanks!
I thought that numeric conversions had to be explicit in Haskell.
That is correct, but here we have numerical literals . If you write 2
, that is not per se an Int
, or an Integer
. We do not know it at that point.
If we then for instance write 2 / 3
, then Haskell will derive that we use a function (/) :: Fractional a => a -> a -> a
, so it concludes that 2
and 3
should be Fractional
, so in this case it will use a floating point parser to parse the 2
literal.
In case you would however explicitly state that 2
is an Int
, then it will go wrong:
Prelude> (2 :: Int) / 3
<interactive>:4:1: error:
• No instance for (Fractional Int) arising from a use of ‘/’
• In the expression: (2 :: Int) / 3
In an equation for ‘it’: it = (2 :: Int) / 3
So by forcing Haskell to use an Int
, Haskell sees no way to parse it as a type that supports the (/)
function.
Now to make it more specific to your question, if we analyze sum [1,2,3]
. sum
has type sum :: Num a => [a] -> a
, so in case the elements of the list are Fractional
, then the sum ...
has also a Fractional
type.
For the denominator you actually make an explicit conversion. Indeed, you write fromIntegral (length [1,2,3])
. Now length :: [a] -> Int
returns an Int
. The fromIntegral
will convert any Integral
type to a generic Num
type. So it can convert an Int
to a Float
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.