Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there a nested IO monad, IO (IO ()), as the return value of my function?

Tags:

haskell

Why does this function have the type: deleteAllMp4sExcluding :: [Char] -> IO (IO ()) instead of deleteAllMp4sExcluding :: [Char] -> IO ()

Also, how could I rewrite this so that it would have a simpler definition?

Here is the function definition:

import System.FilePath.Glob
import qualified Data.String.Utils as S

deleteAllMp4sExcluding videoFileName =
  let dirGlob = globDir [compile "*"] "."
      f = filter (\s -> S.endswith ".mp4" s && (/=) videoFileName s) . head . fst 
      lst = f <$> dirGlob
  in mapM_ removeFile <$> lst
like image 417
DJG Avatar asked Nov 28 '22 08:11

DJG


1 Answers

<$> when applied to IOs has type (a -> b) -> IO a -> IO b. So since mapM_ removeFile has type [FilePath] -> IO (), b in this case is IO (), so the result type becomes IO (IO ()).

To avoid nesting like this, you should not use <$> when the function you're trying to apply produces an IO value. Rather you should use >>= or, if you don't want to change the order of the operands, =<<.

like image 141
sepp2k Avatar answered Nov 30 '22 23:11

sepp2k