Reputation: 25
I want to write a simple recursive function with 3 input parameters and 1 output parameter:
getLengthOfNumber :: (String, Int, Int) -> Int
getLengthOfNumber (n, i, res)
| isCharDigit(n!!i+1) = getLengthOfNumber (n, i+1, res+1)
| otherwise = res
Why does Hugs throw me the Error "Instance of Num Char required for definition of getLengthOfNumber"?
Upvotes: 1
Views: 562
Reputation: 477190
Because it interprets:
n!!i+1
as:
(n!!i) + 1
It thus first obtains the i
-th character of the string, and then aims to add 1
to it. Now in Haskell one can define a custom number type. So here you could add that character and 1
together, but only if that character is a number.
But that being said, the above will not work even by fixing the brackets. You did not instruct when to stop iterating: for the string "123"
, it would eventually obtain the last character, and then raise an "index too large" error when it reaches the end of the string. Furthermore !!
is not efficient: it requires O(k) to access the k-th element, making this algorithm a quadratic one.
What you here can use is takeWhile :: (a -> Bool) -> [a] -> [a]
and length :: [a] -> Int
: first take the longest prefix of character, and then take the length of that list, like:
getLengthOfNumber :: String -> Int
getLengthOfNumber = length . takeWhile isCharDigit
Upvotes: 1
Reputation: 57590
!!
has higher priority than +
, so n!!i+1
is parsed as (n !! i) + 1
, which tries to add one to an element of a string, which only works if Char
is a number. You should instead write n !! (i+1)
.
Upvotes: 3