I have the following code but I feel it is too ugly and imperative. Would anybody rephrase it to be more functional? (I messed with MaybeT but could not make it work) Applicative answers welcome as well.
getString :: IO String
pred :: String -> Bool
f :: String -> String
result :: IO (Maybe String)
result = do
s <- getString
if pred s
then return $ Just $ f s
else return Nothing
EDIT: A follow-up question: what if both pred and f also return results within IO (should I split this out into a separate question?)
getString :: IO String
pred :: String -> IO Bool
f :: String -> IO String
result :: IO (Maybe String)
result = do
s <- getString
b <- pred s
if b
then Just <$> f s
else return Nothing
I would begin by taking the logic here out of the
IOmonad. Your function can then be written asYou could probably write
fooin different ways using some fancy combinators, but I don’t think that’s necessary here. The most important thing is to get your logic out ofIOso that it’s easier to test.