Home > Back-end >  How to get a pair (tuple) of integer and float?
How to get a pair (tuple) of integer and float?

Time:11-09

I'm very much a beginner in Haskell, I'm trying to create a tuple of 2 elements, the first being an integer, and the second being a float. Example:

f1 n = [(x, x) | x <- [1 .. n]]
f2 n = [(x, 1 / x) | x <- [1 .. n]]

> f1 5
[(1,1),(2,2),(3,3),(4,4),(5,5)]

> f2 5
[(1.0,1.0),(2.0,0.5),(3.0,0.3333333333333333),(4.0,0.25),(5.0,0.2)]

f1 behaves as expected, returning a list of tuples of two integers.

f2 returns a list of tuples of two floats, but I was expecting it to return a list of tuples of one integer and one float.

How would I preserve the first tuple element type as integer, such that the output of f2 5 would look like: [(1,1.0),(2,0.5),(3,0.3333333333333333),(4,0.25),(5,0.2)]

CodePudding user response:

The reason this happens is that the compiler sees 1/x, which requires not only the result to be floating (Fractional, actually) but also the argument x. This is because the numerical operators in Haskell have all-same-type signatures

(/) :: Fractional a => a -> a -> a

I.e. the compiler infers that x must already have floating type as well, and thus the left element of the tuple ends up as a float.

You can prevent this by dividing not by x itself but instead allowing for conversion:

Prelude> [(x, 1 / fromIntegral x) | x <- [1 .. 9]]
[(1,1.0),(2,0.5),(3,0.3333333333333333),(4,0.25),(5,0.2),(6,0.16666666666666666),(7,0.14285714285714285),(8,0.125),(9,0.1111111111111111)]

Additionally, one thing you should always try when the types don't seem right is to add an explicit signature. This way you can also enforce the computation to be carried out in other, perhaps more suitable types such as Rational:

Prelude> [(x, 1 / fromIntegral x) | x <- [1 .. 9]] :: [(Int, Rational)]
[(1,1 % 1),(2,1 % 2),(3,1 % 3),(4,1 % 4),(5,1 % 5),(6,1 % 6),(7,1 % 7),(8,1 % 8),(9,1 % 9)]

Also, you'll then get a clear-cut compiler error if you try something that doesn't work, instead of silently unexpected results.

  • Related