Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is `forM_` idiomatic Haskell?

Tags:

haskell

I tend to fall into the use of forM_ in Haskell which is quite like .each in Ruby or foreach in Scala.

import Control.Monad (forM_)
import Network.BSD (getHostByName, hostAddresses)
import Network.Socket (inet_ntoa)
import System.Environment (getArgs)

resolve address = do
  ent <- getHostByName address
  mapM inet_ntoa (hostAddresses ent)

main = do
  args <- getArgs
  args `forM_` (\address -> do
    ips <- resolve address
    ips `forM_` (\ip -> putStrLn $ address ++ "\t" ++ ip))

It doesn't seem to be idiomatic to me but using mapM_ seems clumsy. Is there an idiomatic way of rewriting this code?

like image 315
Steven Shaw Avatar asked Aug 23 '16 11:08

Steven Shaw


1 Answers

It is, though you'd probably better using just for_ :: (Foldable t, Applicative f) => t a -> (a -> f b) -> f () from Data.Foldable.

Also by using it as prefix (i.e. normal function), the code looks like an "ordinary" imperative code:

main = do
    args <- getArgs
    for_ args $ \address -> do
        ips <- resolve address
        for_ ips $ \ip -> putStrLn $ address ++ "\t" ++ ip

P.S. Applicative versions of Monadic "traversals":

  • mapM ~ traverse
  • mapM_ ~ traverse_
  • forM ~ for
  • forM_ ~ for_
like image 82
phadej Avatar answered Nov 08 '22 02:11

phadej