Georg Natter
Georg Natter

Reputation: 25

Haskell - Instance of Num Char required for definition of a function

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

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

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

jwodder
jwodder

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

Related Questions