Reputation:
I'm trying to write a function that returns the first digit in a String
, and if there isn't one then the function should return 1
.
Example:
firstNumber "Example456"
should return 4
because that is the first digit in the String
.
firstNumber "Example"
should return 1
because there is no digit.
This is what I have so far:
firstNumber :: String -> Int
firstNumber = read . maximumBy (length) . map (isDigit)
Can anyone help me here?
Upvotes: 0
Views: 586
Reputation: 54058
Returning 1
if no number is found isn't very good, what if the string contains the number 1
and that was the first one? Instead, you could use the Maybe
data type that represents either a failed computation with Nothing
or a valid return value with Just
.
You could do something like
firstNumber :: String -> Maybe Int
firstNumber s = fmap digitToInt $ listToMaybe $ filter isDigit
But you'll need Data.Maybe
imported to get listToMaybe
. Then you can use it as
> firstNumber "example"
Nothing
> firstNumber "example456"
Just 4
If you did want to return 1
on a failed search then you could just do
firstNumberOr1 :: String -> Int
firstNumberOr1 = fromMaybe 1 . firstNumber
The fromMaybe
function has the definition
fromMaybe :: a -> Maybe a -> a
fromMaybe default Nothing = default
fromMaybe default (Just a) = a
So fromMaybe 1
will return 1
when given Nothing
, and just unwrap whatever value was in the Just
if given that.
Upvotes: 5
Reputation: 22460
You can do:
headDef [] = 1
headDef (x:_) = read [x]
firstNumber = headDef. filter isDigit
s="Example456"
Output:
*Main> firstNumber s
4
*Main> firstNumber "ex"
1
*Main>
The function headDef
tries to retrieve the first element of a list and replace it with a default value if the list is empty. You can change the default value/type in headDef
to something else if necessary.
Upvotes: 2