0

I'm trying to understand how the dot operator works. Here's an example:

main = do
    ns <- getNetworkInterfaces
    mapM_ (putStr . showInterface) ns

I know that mapM_ accepts a function and Monad. "ns" is a Monad. But how actually the part (putStr . showInterface) works in terms of Haskell grammar or syntax in this particular example? Once again: in this particular example. Also, which function will be called first: putStr or showInterface?

Jushiti
  • 165
  • 1
  • 10
  • 1
    Possible duplicate: https://stackoverflow.com/questions/631284/dot-operator-in-haskell-need-more-explanation , https://stackoverflow.com/questions/2486564/what-does-a-fullstop-or-period-or-dot-mean-in-haskell – Sibi Apr 17 '16 at 09:35

1 Answers1

4

it's just composition - it does one after the other (from the right) - so

(putStr . showInterface) n

is just

putStr (showInterface n)

so in a sense showInterface is called first


please note that your understanding is a bit flawed here - ns is not the monad here that matters (it's a list - it's the Foldable part in the newer versions of mapM_) - the monad that matters is IO and mapM_ accepts a monadic action and a list of things to put into that action (one by one) - so here every item in ns is put into the action

putStr . showInterface

and of course each one will first be used int the pure function showInterface (which obviously produces a string) and then be printed to stdout using putStr (this is the monadic action that needs the mapM_)


if in doubt check the signature

If you want to find out which part matters look at the signature

In case of mapM_ it's:

mapM_ :: (Monad m, Foldable t) => (a -> m b) -> t a -> m ()

forget the Foldable t here - it's your list:

mapM_ :: Monad m => (a -> m b) -> [a] -> m ()

now what can the m be?

Well you use putStr . showInterface for the first argument - now I don't know exactly what showInterface is - but as you compose it with putStr the resulting type should be something like

putStr . showInterface :: SomeInterfaceType -> IO ()

and now you should see that: m ~ IO, a ~ SomeInterfaceType and b ~ () - notice that the monad is IO! - and you get:

mapM_ (putStr . showInterface) :: [SomeInterfaceType] -> IO ()
Random Dev
  • 51,810
  • 9
  • 92
  • 119
  • list is a Monad, isn't it? – Jushiti Apr 17 '16 at 07:18
  • 1
    yes it is - but the one that matters here is the `IO` monad - do make list the one that matters you would need a action of type `a -> [b]` - try and play with `mapM (\x -> [x,x]) (Just 5)` do see the difference with a different `Foldable` (`Maybe` in this case) as well – Random Dev Apr 17 '16 at 07:51
  • To get a better feel for how list as a monad works, try `mapM (\x -> [x, -x]) [1,2,3]`, compared to `map (\x -> [x,-x]) [1,2,3]`. (IMO, the example mapping over a `Maybe` hides the nondeterministic interpretation of the list monad that `mapM` allows.) – chepner Apr 17 '16 at 12:13
  • @chepner yes - but so you can mistake the monad and the foldable again ;) – Random Dev Apr 17 '16 at 12:14
  • We need a bigger, non-list traversable, like a tree :) – chepner Apr 17 '16 at 12:20