Reputation: 10375
I am trying to get a list of the digits from a number, here is my code:
digits x = if x > 0 then (i : digits (floor (x / 10))) else [i]
where i = (mod x 10)
The error I get for this code is:
No instance for (Integral a0) arising from a use of ‘it’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
what am I doing wrong?
Upvotes: 1
Views: 58
Reputation: 32309
To elaborate on Carsten's comment, the problem is that Haskell infers the type signature
digits :: (RealFrac a, Integral a) => a -> [a]
when what you wanted was
digits :: Integral a => a -> [a]
The reason it infers the former is that you use (/)
and floor
, which are defined in the Fractional
and RealFrac
classes. As leftaroundabout points out, this isn't really a problem until you try to run your function with an actual number, at which point Haskell fails to find a good number type to default to (Haskell number literals are actually polymorphic, and there are special defaulting rules for when you don't explicitly declare a type), hence the weird error message. You would get a more descriptive error message if you tried something like digits (1 :: Int)
:
<interactive>:19:1: error:
• No instance for (RealFrac Int) arising from a use of ‘digits’
• In the expression: digits (1 :: Int)
In an equation for ‘it’: it = digits (1 :: Int)
The fix, as Carsten pointed out, is to use div
instead of (/)
and floor
.
Upvotes: 2