[Haskell-beginners] general structuring of "foreach" logic in IO

Patrick Wheeler patrick.john.wheeler at gmail.com
Mon Apr 14 09:34:47 UTC 2014


@John

It looks like you are looking for `forM_` from Control.Monad:
http://hackage.haskell.org/package/base-4.7.0.0/docs/Control-Monad.html#v:forM_

That way you can write code that looks like:

main = do
    myargs <- getArgs
    forM_ myargs $ \s -> do
        putStrLn s
        putStrLn $ "Second string" ++ s

This is just `mapM_` with the its two parameters fliped. `forM_` is defined
in a an idiomatic fashion, with the `flip`(prelude function) function.

Definition of forM_
http://hackage.haskell.org/package/base-4.7.0.0/docs/src/Control-Monad.html#forM_

Magnus solution has been used so often by some people that some have
created idioms around it.

om f m x = m >>= flip f x

main = do
    om forM_ getArgs $ \s -> do
        putStrLn s
        putStrLn $ "Second string: " ++ s

You can read the discussion around om:
http://www.reddit.com/r/haskell/comments/1i2zmq/a_useful_function_om/

Hope that helps.

Patrick


On Sun, Apr 13, 2014 at 1:48 AM, Magnus Therning <magnus at therning.org>wrote:

> On Sat, Apr 12, 2014 at 08:29:09AM -0500, John M. Dlugosz wrote:
> > This works:
> >
> > main = do
> >     myargs <- getArgs
> >     mapM_ (\s -> putStrLn s ) myargs
> >
> > and imagine that the "body" will be substantial rather than just a
> putStrLn.
> > My gut instinct is that the code ought to be arranged as:
> >
> >       <any needed keywords or punctuation> and <the collection of items>
> >       <body to perform for every element
> >               ...
> >               ...
> >               >
> >
> > Meanwhile, there is no need to name the result of getArgs into myargs.
> >
> > So, getArgs is of type IO [String], and I want to apply that in the
> > manner of a list. Without the Monad wrappers, plain
> >       map ( blah ) strings
> > could be ( blah ) <$> strings, and in this particular case I don't
> > see a reversed-arg version, although there is one for <*> (as <**>).
> > But, for monad stuff in general there are reversed arrows for
> > (most?) everything, and that's where I'm heading.
> >
> > So the first question is, how do I do the equivalent
> > map-as-nondeterministic-apply when the strings is further wrapped in
> > IO, as is the function being applied.
> >
> >       getArgs >>= mapM_ (\s -> putStrLn s )
> >
> > does double-duty of moving the argument from last place to the left,
> > as it makes use of eta reduction.  Because I have two things going
> > on (list applicative and IO monad) I'm losing the slickness of using
> > applicative syntax.  Is there a nice way to make these work
> > together?
> >
> > And more generally, how would you write such a construct?  I'm
> > naturally biased with my knowledge in other languages, so maybe
> > there's a completely different "normal" way of approaching this?
>
> I'm not entirely sure I get what you are asking for, but I'll take a
> stab and just let me know if I'm completely off the mark.
>
> If all you want is keep the 'string generator' on the right-hand side,
> then you have (=<<):
>
>     mapM_ putStrLn =<< getArgs
>
> Personally I often like keeping the 'string generator' on the left
> (i.e. using (>>=) because when the expression to be mapped grows it
> allows this structuring of the code:
>
>     getArgs >>= mapM_ $ \ s -> do
>         ...
>
> /M
>
> --
> Magnus Therning                      OpenPGP: 0xAB4DFBA4
> email: magnus at therning.org   jabber: magnus at therning.org
> twitter: magthe               http://therning.org/magnus
>
> Perl is another example of filling a tiny, short-term need, and then
> being a real problem in the longer term.
>      -- Alan Kay
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
>


-- 
Patrick Wheeler
Patrick.John.Wheeler at gmail.com
Patrick.J.Wheeler at rice.edu
Patrick.Wheeler at colorado.edu
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20140414/666d84ad/attachment.html>


More information about the Beginners mailing list