1

I have the following function:

probIndex idx xs = 
  xs!!idx+mult
  where mult = round(2**idx)

When I try to load it in ghci, it shows the following error:

Prelude> :load bn.hs
[1 of 1] Compiling Main             ( bn.hs, interpreted )

bn.hs:31:16:
    No instance for (RealFrac Int)
      arising from a use of `round'
    Possible fix: add an instance declaration for (RealFrac Int)
    In the expression: round (2 ** idx)
    In an equation for `mult': mult = round (2 ** idx)
    In an equation for `probIndex':
        probIndex idx xs
          = xs !! idx + mult
          where
              mult = round (2 ** idx)

bn.hs:31:23:
    No instance for (Floating Int)
      arising from a use of `**'
    Possible fix: add an instance declaration for (Floating Int)
    In the first argument of `round', namely `(2 ** idx)'
    In the expression: round (2 ** idx)
    In an equation for `mult': mult = round (2 ** idx)
Failed, modules loaded: none.
Prelude> 

Why does it occur? 2**idx returns float, but round converts it to integer, so everything is an integer. Where do those "Floating" and "RealFrac" come from?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Evgenii.Balai
  • 939
  • 13
  • 30

3 Answers3

4

(**) is the power function for floating numbers. For integers you should use integer power (^):

probIndex idx xs = 
  xs!!idx + 2^idx
Tarmil
  • 11,177
  • 30
  • 35
3

Your code is parsed as

probIndex idx xs = (xs !! idx) + mult
  where mult = round (2**idx)

Now,

Prelude> :t (**)
(**) :: (Floating a) => a -> a -> a

which makes it idx :: (Floating a) => a, but

Prelude> :t (!!)
(!!) :: [a] -> Int -> a

which makes it idx :: Int. Hence the unsuccessful attempts to find (Floating Int) instance. Similarly with RealFrac which comes from round :: (RealFrac a, Integral b) => a -> b.

(shameless plug: you can see more about type derivations e.g. in this answer :) ).

Community
  • 1
  • 1
Will Ness
  • 70,110
  • 9
  • 98
  • 181
3

The expression xs!!idx+mult is parsed as

(xs !! idx) + mult

The type of (!!) is

>> :t (!!)
(!!) :: [a] -> Int -> a

which means that idx :: Int. Now you have

>>> mult = round (2 ** idx)

and the type of (**) is

>>> :t (**)
(**) :: Floating a => a -> a -> a

and since idx :: Int you can specialize to (**) :: Floating Int => Int -> Int -> Int, which is where you run into a problem - Int is not an instance of Floating. To get around this you can instead write

>>> mult = round (2 ** fromIntegral idx)

which will coerce idx into a fractional type, and satisfy the type checker. Alternatively, if the parsing of the original expression is not what you intended, you can simply replace it with

xs !! (idx + mult) where mult = ...

and your code should type check correctly.

Chris Taylor
  • 46,912
  • 15
  • 110
  • 154
  • Thanks, it helps. I am sorry for another newbie question. How to read (**) :: Floating a => a -> a -> a ? I understand that a->a->a is a function which takes two arguments of type a and returns a value of type a, but how to interpret "Floating a =>"? – Evgenii.Balai Mar 21 '14 at 23:07
  • 1
    `Floating a =>` means "this type works for any type `a` that is an instance of `Floating`". So `a` can be `Float`, `Double` or a couple others (listed [here](http://hackage.haskell.org/package/base-4.6.0.1/docs/Prelude.html#t:Floating)) – Tarmil Mar 21 '14 at 23:11