bertramscharpf
bertramscharpf

Reputation: 323

Floating Rational type error calculating sqrt

When I ask GHCi for the golden section, I get the correct answer:

Prelude> (-1 + sqrt 5) / 2
0.6180339887498949

Doing the same inside "xmonad.hs" (for tiling), I receive:

xmonad.hs:32:22: error:
    • No instance for (Floating Rational) arising from a use of ‘sqrt’
    • In the second argument of ‘(+)’, namely ‘sqrt 5’
      In the first argument of ‘(/)’, namely ‘(- 1 + sqrt 5)’
      In the expression: (- 1 + sqrt 5) / 2

What happens here, what helps?

Upvotes: 0

Views: 92

Answers (1)

K. A. Buhr
K. A. Buhr

Reputation: 50819

If you ask GHCi for the value of this expression and request a Rational result, you get the same error:

Prelude> (-1 + sqrt 5) / 2 :: Rational

<interactive>:1:7: error:
    • No instance for (Floating Rational) arising from a use of ‘sqrt’
    • In the second argument of ‘(+)’, namely ‘sqrt 5’
      In the first argument of ‘(/)’, namely ‘(- 1 + sqrt 5)’
      In the expression: (- 1 + sqrt 5) / 2 :: Rational
Prelude> 

The issue is that the Rational type doesn't have a Floating instance, and you appear to be using the expression (-1 + sqrt 5) / 2 in a context where a Rational is expected.

This makes sense. The Rational type is intended to represent exact calculations on rational numbers, and there is no exact rational representation of this expression.

The Data.Ratio package includes the approxRational function to get a nearby rational approximation to a non-rational expression, so you should be able to write:

approxRational ((-1 + sqrt 5) / 2) 0.001

to get a rational that's within 0.001 of your desired result:

Prelude> import Data.Ratio
Prelude Data.Ratio> approxRational ((-1 + sqrt 5) / 2) 0.001
21 % 34

Upvotes: 3

Related Questions