Reputation:
step :: [Int] -> String -> [Int]
step (x:y:ys) "*" = (x*y):ys
step (x:y:ys) "+" = (x + y):ys
step (x:y:ys) "-" = (y - x):ys
step xs numString = read numString : xs
I am expanding my knowledge from,
http://learnyouahaskell.com/functionally-solving-problems, I wanna try to do some eroor handling using Maybe
. Can anyone give me some hint or any useful keyword on defining below function(if my idea is right)? I wanna return Just sts
when I successfully input value and Nothing
when I didn't. Dunno if my concept is right, anyone correct me.
step2:: [Int] -> String -> Maybe [Int]
Upvotes: 3
Views: 224
Reputation: 48572
Your type signature is right. Here's one possible implementation:
import Text.Read (readMaybe)
step2 :: [Int] -> String -> Maybe [Int]
step2 (x:y:ys) "*" = Just $ (x*y):ys
step2 (x:y:ys) "+" = Just $ (x + y):ys
step2 (x:y:ys) "-" = Just $ (y - x):ys
step2 xs numString | Just num <- readMaybe numString = Just $ num:xs
step2 _ _ = Nothing
The basic idea is for all of your existing cases, wrap them in Just
, and then at the end, have a catch-all of Nothing
. There's a bit of special handling for read
, since it just throws an error if it fails, so you need to use readMaybe
and pattern-match on it instead.
There's another way you can write it that shortens a bit:
import Text.Read (readMaybe)
step2 :: [Int] -> String -> Maybe [Int]
step2 (x:y:ys) "*" = Just $ (x*y):ys
step2 (x:y:ys) "+" = Just $ (x + y):ys
step2 (x:y:ys) "-" = Just $ (y - x):ys
step2 xs numString = fmap (:xs) (readMaybe numString)
We were able to make this change for a few reasons:
readMaybe
returns its result wrapped in the same type that our function will (Maybe
)Maybe
) is a Functor
Because of that, we can apply fmap
to the output of readMaybe
to combine the last two cases. For the Maybe
type, fmap
works by leaving a Nothing
as a Nothing
, or changing a Just x
to Just (f x)
, which is exactly what we were doing anyway.
Upvotes: 4