Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No instance for (Floating Int)

I am learning Haskell. I have created function which returns multiplication table up to 'n' in base 'b'. Numbers are padded to 'w' digits. As the last step, I want to compute 'w' automatically. Why does this not compile?

-- Number of digits needed for the multiplication table n*n in base 'base'
nOfDg :: Int -> Int-> Int 
nOfDg n base = 1 + floor ( logBase base (n*n)) 

error:

No instance for (Floating Int)
     arising from a use of `logBase' at C:\haskel\dgnum.hs:4:24-38
   Possible fix: add an instance declaration for (Floating Int)
   In the first argument of `floor', namely `(logBase b (n * n))'
   In the second argument of `(+)', namely `floor (logBase b (n * n))'
   In the expression: 1 + floor (logBase b (n * n))
like image 813
danatel Avatar asked Dec 28 '09 17:12

danatel


3 Answers

logBase takes two parameters which implement the floating typeclass. You'll need to call fromIntegral on the parameters before passing them to logBase. This compiled for me with 6.10.3:

nOfDg :: Int -> Int-> Int
nOfDg n base = 1 + floor ( logBase (fromIntegral base) (fromIntegral (n*n)))

You have to remember that Haskell is very strongly typed, so you can't just assume that the Int parameters supplied to your function will automatically be coerced to the floating numbers that log functions generally take.

like image 166
maxaposteriori Avatar answered Nov 04 '22 21:11

maxaposteriori


logBase is declared to work on floating point types. Int is not a floating point type and there is no automatic conversion in Haskell. Try this:

-- Number of digits needed for the multiplication table n*n in base 'base'
nOfDg :: Int -> Float -> Int
nOfDg n base = 1 + floor (logBase base (fromIntegral (n*n)))
like image 28
Dan Dyer Avatar answered Nov 04 '22 23:11

Dan Dyer


From the Prelude :

logBase :: Floating a => a -> a -> a

It means that using logBase you must be using a floating type. But Int is not a floating Type, and there is no automatic conversion for numeric types, so you have to convert it from Int to a Floating type :

nOfDg n base = 1 + floor ( logBase (toEnum base) (toEnum n))

the toEnum function take an int as parameter and return an "Enum" type. The good part is that Float is an instance of Enum, so you could use it

toEnum :: Enum a => Int -> a

You should read/document you about standard type classes in haskell for numeric types (Num,Fractional,Integral, Floating...) as they often pop-up in code, learning conversions could be useful.

Edit : this Haskell Wiki Book provide a very useful graphic of relationship between standards type class, including numeric types.

like image 3
Raoul Supercopter Avatar answered Nov 04 '22 23:11

Raoul Supercopter