adsbb12345
adsbb12345

Reputation: 31

String to List of Int

I would like to incorporate Maybe [int] into this.

The code should take a string and filter out spaces turning it into a list of integers and if their are letters return Nothing.

text2digits :: String -> [Int]
text2digits s = case s of
    []          -> []
    x:xs        
        |isDigit x      -> digitToInt x :text2digits (filter (/= ' ') xs)
        |otherwise      -> undefined

input "1233 5687"  output: [1,2,3,3,5,6,8,7]
input "a89"       required output : Nothing 
                  current output: undefined

I have tried this but it shows up a list of errors

text2digits :: String -> Maybe [Int]
text2digits s = case s of
    []          -> Just []
        x:xs        
        |isDigit x      -> Just digitToInt x :text2digits (filter (/= ' ') xs)
        |otherwise      -> Nothing

Upvotes: 3

Views: 286

Answers (1)

Igor Drozdov
Igor Drozdov

Reputation: 15045

What is wrong with the code, that you've specified for text2digits :: String -> Maybe [Int]?

The problem is in this line:

digitToInt x :text2digits (filter (/= ' ') xs)

text2digits returns value of Maybe [Int] type, but (:) expects it to be [Int].

In order to fix it, you can use fmap or <$> to apply a function to a structure inside the functor Maybe:

import Data.Char

text2digits :: String -> Maybe [Int]
text2digits s = case s of
    [] -> Just []
    x:xs
      |isDigit x      -> ((digitToInt x) :) <$> text2digits (filter (/= ' ') xs)
      |otherwise      -> Nothing

main = print $ text2digits "1233 5687"

Or probably you can use traverse to refactor the function a bit:

import Data.Char

text2digits :: String -> Maybe [Int]
text2digits s =
  traverse digitToMaybeInt $ filter (/= ' ') s
  where
    digitToMaybeInt x
      | isDigit x = Just $ digitToInt x
      | otherwise = Nothing

main = print $ text2digits "89"

Upvotes: 5

Related Questions