Question

I got a function that takes a string and search it for decimals and output them. What I got so far is:

getDecimal :: String -> [Int]
getDecimal[] = 0
getDecimal (x:y:xs) = 
    if
        isDecimal x y
    then 
        //output list
    else
        getDecimal xs

(for example: getDecimal "he12llo035" will output 12 , 035

But cant fill in the then because I simply cant find the solution, can you guys give me tips?

Was it helpful?

Solution

You try to tackle this in an imperative-like way: "look at this part of the list, is it what we want? Well then do that thing... oh, no it's not? Well then proceed there..."

It sure can't hurt to know how to implement it in such terms as well, but anyway better to learn more concise, explanative, declarative approaches right away. "The Haskell way".

That normally means roughly: split up your goal in subtasks. You'll first want to group all numbers down to one element, rather than a group of characters within the list. Well, you can hoogle for "group"!

Indeed there's a group comparison, but it simply puts together elements that are equal. That's a bit too strong, we sure want to allow different digits in each number! groupBy is the version that allows this. So, according to what do we want to group? Well, depending on whether it's a number. There's a nice helper from the Data.Function module that allows you to formulate this very much to the point:

                groupBy ((==) `on` isDigit)

Meaning, we want to group such elements that have "the same status of digit-being".

After that, you'll have a lists of strings, and know each string is either a complete number, or something unrelated. The latter is to be thrown away...

                filter (isDigit . head)

(I've just checked if the first character is a digit; the following are sure to be as well because that's what we've grouped by.

Now you've a list of numbers still in string form, all that's left to be done is parse (read!) each of them.

import Data.Char
import Data.List
import Data.Function

getDecimalNums :: String -> [Int]
getDecimalNums = map read . filter (isDigit . head) . groupBy ((==) `on` isDigit)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top