[Haskell-cafe] Re: mixing map and mapM ?

Maciej Piechotka uzytkownik2 at gmail.com
Thu May 6 13:53:56 EDT 2010


On Thu, 2010-05-06 at 12:09 +0100, Ben Millwood wrote:
> On Thu, May 6, 2010 at 11:51 AM, Bill Atkins <watkins at alum.rpi.edu> wrote:
> > Almost - "liftM modificationTime" has type Status -> IO EpochTime.  Like
> > other IO functions (getLine, putStrLn), it returns an IO action but accepts
> > a pure value (the modification time)
> 
> ghci> :m +Control.Monad System.Posix.Files
> ghci> :t liftM modificationTime
> liftM modificationTime
>   :: (Monad m) => m FileStatus -> m System.Posix.Types.EpochTime
> 
> where m = IO in this case.
> 
> > Also, I like this style:
> > import Control.Applicative ((<$>))
> > blah = do
> >   times <- mapM (PF.modificationTime <$> PF.getFileStatus) filenames
> >   ...
> > The <$> operator evaluates to fmap so it's a cleaner way to apply a pure
> > function to an IO value.
> 
> Usually I'd agree but in fact PF.getFileStatus is not an IO value, but
> an IO function, so you need to map over its result:
> 
> mapM ((PF.modificationTime <$>) . PF.getFileStatus) filenames
> 
> but then you lose the convenience of the <$> as an infix operator, so
> 
> mapM (liftM PF.modificationTime . PF.getFileStatus) filenames
> 
> is probably clearer in this case. Or, if you're feeling particularly silly:
> 
> mapM (fmap fmap fmap modificationTime getFileStatus) filenames

I usually use <.> (IMHO should be in Control.Applicative next to <$>)
which is the same to <$> as . is to $:

g <.> f = fmap g . f :: Functor f => (b -> c) -> (a -> f b) -> a -> f c

times <- mapM (PF.modificationTime <.> PF.getFileStatus) filenames

Regards
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100506/96166c98/attachment.bin


More information about the Haskell-Cafe mailing list