1

I am attempting to raise a number which is of type RealFrac to the power of another number, also of type RealFrac. This question on exponentiation helpfully explains the various exponentiation functions in Haskell, and I believe I need to use (^) in order to preserve any non integer values. But how do I deal with the types? I keep coming up against errors like this:

Could not deduce (Integral a) arising from a use of ‘^’
from the context (RealFrac a)
  bound by the type signature for
             splitFunc :: RealFrac a => a -> a -> a
  at Procedural/City.hs:41:16-42
Possible fix:
  add (Integral a) to the context of
    the type signature for splitFunc :: RealFrac a => a -> a -> a
In the expression: r ^ l
In an equation for ‘splitFunc’: splitFunc r l = r ^ l
Community
  • 1
  • 1
BenJacob
  • 957
  • 10
  • 31

1 Answers1

2

Two issues. Firstly, you do not want (^), but rather (^^) (if your exponents are always integer numbers) or (**) (if you need floating exponents):

Prelude> :t (^)
(^) :: (Integral b, Num a) => a -> b -> a
Prelude> :t (^^)
(^^) :: (Fractional a, Integral b) => a -> b -> a
Prelude> :t (**)
(**) :: Floating a => a -> a -> a

Secondly, RealFrac covers not only floating point numbers but also, for instance, exact fractions. If you really need your function to use (**) and work with any RealFrac you will need to convert the values with realToFrac:

Prelude> :t realToFrac 
realToFrac :: (Fractional b, Real a) => a -> b

Naturally, if you define splitFunc r l = realToFrac r ** realToFrac l and pass exact fractions (e.g. something of type Ratio Integer) to it, the extra precision of exact fractions will be lost, as (**) is a floating point operation.

duplode
  • 33,731
  • 7
  • 79
  • 150
  • Ah yes sorry i meant **. That works perfectly, thank you - its taking me a bit of time to get used to haskells type system. – BenJacob Aug 01 '15 at 17:31