Reputation: 49
I'm getting a frustrating error when I try to extract the first two digits of a number. First, I work out the length of digit using log, then I divide the number by the 10^(length of digit - 2)
to extract the first two digits. The len and divisor functions work fine, but the firstTwo function fails, and I don't understand this because it seems so straight forward. I even tried adding {-# LANGUAGE FlexibleContexts #-}
, but nothing. Please assist. Here's the code:
len n = (+) 1 $ truncate $ logBase 10 n -- length of a digit
divisor n = 10 ^ (len n - 2)
firstTwo n = div n divisor
The error I get is:
Non type-variable argument in the constraint: Integral (r -> a)
(Use FlexibleContexts to permit this)
When checking that ‘firstTwo’ has the inferred type
firstTwo :: forall a r.
(Floating r, Integral (r -> a), Num a, RealFrac r) =>
(r -> a) -> r -> a
Upvotes: 0
Views: 1887
Reputation: 176
Convert your number to String.
Check if the string contains 2 or more chars.
If the check is successful, take first 2 chars from your string and convert them to Int (or put those chars in tuple or do with them whatever you want).
Do something with the case if your number contains less than 2 digits (throw error for example).
firstTwo :: Integer -> Int
firstTwo n
| (length . show $ n) >= 2 = read . take 2 . show $ n
| otherwise = error "The number contains less than 2 digits"
Upvotes: 1
Reputation: 15967
As you seem to be a beginner my very first advice would be, to add type information as much as possible. At least for every top level (function) definition. This helps you, the compiler and everyone else reading your code understanding your intent.
Now to your problem: you try to divide a number n
by a function divisor
div n (divisor n)
Should do the trick, well there is one small bit missing - logBase
does not work on integers, while div
does only work on integers. So you need to call fromInteger
first to convert.
An alternative that would work with a small adjustment for negative numbers could be take 2 . show
.
Upvotes: 3
Reputation: 105876
You use div
on n
and divisor
, but divisor
isn't the same type as n
, it's a function. That's why you end up with Integral (r -> a)
.
Use firstTwo n = div n (divisor n)
, but keep in mind that logBase
only works on Floating
such as Double
and Float
, whereas div
only works on Integral
such as Integer
and Int
. Therefore, it will still not compile, unless you've changed len
's type.
Add type signatures to your function to get better error messages.
Upvotes: 3