[Haskell-cafe] monadic versus aplicative style. These two snips seem to do the same thing yet one has a bug.

Thomas Hartman tphyahoo at gmail.com
Wed Dec 17 11:54:07 EST 2008


Hi,

  I rewrote a piece of code that used applicative to use instead
monadic style, basically because I wanted to adapt it for my own
purposes but hadn't wrapped my head around applicative yet.

  Unfortunately my rewrite had a bug, which I'm still not completely
clear on. (I am guessing it's a laziness mixed with IO issue.)

  I discarded my own version and am using the original now of course,
but I'm curious if anyone has anything to say on the difference
between these two bits of code and, in general if there is any way to
"think" about the difference between monadic and applicative.

  For what it's worth, the code comes from HSTringTemplate (on
hackage). The bug is described in

  http://groups.google.com/group/HAppS/browse_thread/thread/70d4b1fbe8a4c7ac

  Basically, in happs, this bit of code caused an unrelated handler to
not fully pages correctly, where there was more than one image to
load. It took forever to diagnose and track this down. Ugh.

  Thanks, thomas.

-- incorrect behavior
directoryGroup' :: (FilePath -> FilePath -> IO (StringTemplate a)) ->
FilePath -> IO (STGroup a)
directoryGroup' templatereader path = do
    fs <- return . ( filter ((".st" ==) . takeExtension) ) =<<
getDirectoryContents path
    templates <- mapM (templatereader path) fs
    stmapping <- return $ zip fs templates
    return $ groupStringTemplates stmapping

-- correct behavior
--directoryGroup2' :: (Stringable a) => FilePath -> IO (STGroup a)
directoryGroup'2 templatereader path = groupStringTemplates <$>
                      (fmap <$> zip . (map dropExtension)
                       <*> mapM ( templatereader path )
                           =<< filter ((".st" ==) . takeExtension)
                       <$> getDirectoryContents path)


More information about the Haskell-Cafe mailing list