Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GHC says "digits" needs an Int, when it needs an Integral

Tags:

haskell

ghc

As far as I can see, this code snippet should compile without a problem:

import Data.Digits (digits)
-- |convert integer to arbitrary base with specified charset
-- base/radix is charset string length.
-- eg. convert the integer 255 to hex:
--      intToBaseN 255 "0123456789abcdef" = "ff"
numToBaseN :: Integral n => n -> [Char] -> String
numToBaseN num charlst = map (\i -> charlst !! (fromIntegral i)) lst where
    lst = digits (length charlst) num

But GHC complains that the num in the lst expression isn't an Int. But the type of digits is

digits :: Integral n => n -> n -> [n]

it doesn't require an Int as an argument, only something that is an Integral, which the type signature of numToBaseN does as well.

!! requires an Int, which is why it is converted using fromIntegral.

What's going on here?

It compiles if I replace num with (fromIntegral num), but then I lose the ability to convert an Integer (ie. arbitrarily large integers).

like image 626
runeks Avatar asked Aug 04 '15 20:08

runeks


1 Answers

Both arguments to digits need to have the same type and length charlst has the type Int, so num must also have type Int.

It compiles if I replace num with (fromIntegral num), but then I lose the ability to convert an Integer

If you apply fromIntegral to length charlst instead, it will convert it to whichever type num is, so it'll work the way you want.

like image 192
sepp2k Avatar answered Nov 18 '22 17:11

sepp2k