Why can't I add Int and floating point number in haskell

why this does not work: -

(length [1,2,3,4]) + 3.2 

while it works: -

 2+3.3 

I understand that in the first case, the result is Int + Float, but this is not the same in the second case, or Haskell automatically displays the type in the second case: - Num + Num, then how not to do this in the first case?

+4
source share
3 answers

Haskell never does implicit type conversion for you. + only works on two numbers of the same type and gives you that type as a result. Any other use of + is a mistake, as you saw with the example (length [1,2,3,4]) + 3.2 .

However, numeric literals are overloaded in Haskell. 2 can be any numeric type, and 3.3 can be any fractional type. Therefore, when Haskell sees the expression 2 + 3.3 , he can try to find a type that is both "numeric" and "fractional", and treat both numbers as this type so that the addition continues.

More specifically, + is of type Num a => a -> a -> a . 2 by itself is of type Num a => a and 3.3 by itself is of type Fractional a => a . Combining these 3 types, in the expression 2 + 3.3 both numbers can be given the Fractional a => a type Fractional a => a , since all Fractional types are also Num types, and this also satisfies the + type. (If you enter this expression in GHCi, a will be populated as Double , because GHC should use the type to evaluate it by default)

In the expression (length [1,2,3,4]) + 3.2 , 3.2 is still overloaded (and in isolation will be of type Fractional a => a ). But length [1,2,3,4] is of type Int . Since one side is a fixed concrete type, the only way to satisfy the type for + would be to populate a on the other type with Int , but this violates the Fractional constraint; there is no way for 3.2 be Int . So this expression is not well printed.

However, any Integral type (of which Int is one) can be converted to any Num type using fromIntegral (this is actually how integer literals, such as 2 , can be thought of as any numeric type). So (fromIntegral $ length [1,2,3,4]) + 3.2 will work.

+12
source

In the first case, as you said, length [1,2,3,4] explicitly Int and cannot be converted implicitly to Float or to any Fractional instance. While in the second, there is no explicit typing, so Haskell can conclude that a good type is an instance of Fractional . You can see how the numerical literal is processed by the compiler in the corresponding section (ยง6.4.1) of the Haskell 2010 report .

(fromIntegral $ length [1,2,3,4]) + 3.2 : (fromIntegral $ length [1,2,3,4]) + 3.2

+10
source

Integer literals, such as 2 in your second example, are implicitly treated as fromInteger 2 compiler. This means that they are converted to any required numeric type, because fromInteger is polymorphic in return type; in this case, Float used. However, length [1,2,3,4] is of type Int , not a literal, so you need to explicitly convert it.

+7
source

Source: https://habr.com/ru/post/1495896/


All Articles