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

Magnus Therning magnus at therning.org
Sun Apr 13 06:48:35 UTC 2014

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


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://www.haskell.org/pipermail/beginners/attachments/20140413/bdd84de6/attachment.sig>

More information about the Beginners mailing list