3

I have this snippet of a function:

mapM (\x -> do t' <- t; return $ strSwop "if0" ("if" ++ show x) t') [0..(n-1)]

With

strSwop :: String -> String -> String -> String
t :: IO String

It works as expected but I don't like the IO construct withing the lambda. How can it be written differently? I come out of the monad just to be wrapped again next line. Feels ugly.

If I do it this way:

mapM (\x -> t >>= strSwop "if0" ("if" ++ show x) t) [0..(n-1)]

It complains (obviously) about the return signature of strSwop :( strSwop is just a string replacement function. Is there a way to correctly write this? Thanks.

-- EDIT --

Just figured it out ...

Works out:

mapM (\x -> liftM (strSwop "if0" ("if" ++ show x)) t) [0..(n-1)]
1
  • Off-topic: On stackoverflow, it is generally considered polite to accept the answer (click on the tick below the answer's score), which helped you solve the problem. It helps not only the user who answered it, but it also helps you, because it provides other users with an incentive to answer your questions. Commented Feb 24, 2012 at 13:17

2 Answers 2

4

I would suggest liftM or <$>

import Control.Applicative
mapM (\x -> strSwop "if0" ("if" ++ show x) <$> t) [0..(n-1)]
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much. I just actually figured this out seconds ago. I did it with liftM exactly as you suggested. It worked out: mapM (\x -> liftM (strSwop "if0" ("if" ++ show x)) t) [0..(n-1)]
@r.sendecky: If an answer helped you, you should click the check mark underneath it to accept it :)
2

Let's simplify your code step by step.

mapM (\x -> do t' <- t; return $ strSwop "if0" ("if" ++ show x) t') [0..(n-1)]

Start by breaking off the pure code - let's convert [0..(n-1)] into a list of [String -> String] using currying:

mapM (\f -> do t' <- t ; return (f t)) $ map (\x -> strSwop "if0" ("if" ++ show x)) [0..(n-1)]

Now do t' <- t ; return (f t) is pretty common - that's just fmap f t'

mapM (\f -> fmap f t') $ map (\x -> strSwop "if0" ("if" ++ show x)) [0..(n-1)]

And \f -> fmap f t' is just \f -> flip fmap t' f or flip fmap t'

mapM (flip fmap t') $ map (\x -> strSwop "if0" ("if" ++ show x)) [0..(n-1)]

Cleaning up the pure half: \x -> strSwop "if0" ("if" ++ show x) is the same as \x -> strSwop "if0" $ ("if" ++) (show x) which is the same as \x -> strSwop "if0" . ("if"++) $ show x which is the same as strSwop "if0" . ("if"++) . show

mapM (flip fmap t') $ map (strSwop "if0" . ("if"++ ) . show) [0..(n-1)]

Now let's fuse the two parts back together. mapM f . map g = sequence . map f . map g = sequence . map (f . g) = mapM (f . g):

mapM (flip fmap t' . strSwop "if0" . ("if"++) . show) [0..(n-1)]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.