Chetan Yewale
Chetan Yewale

Reputation: 312

Getting error due to IO a type of parameter

I am implementing a feature which is as follows: User will request for the directory contents via HTTP request. The directory path will be passed inthe request. In response, I will send a JSON containing the list of files for that directory path. IO Error handling is taken care of. I have implemented most of the part. But I am getting an error. The error is:

Couldn't match expected type ‘Either IOException [FilePath]’
            with actual type ‘IO (Either IOException [FilePath])’
• In the first argument of ‘getJsonRepForFiles’, namely ‘files’

The code snippet is as follows:

getInfoOfDirR::Handler Value
getInfoOfDirR = do
             -- files will have type IO (Either IOException [FilePath])
                     files <- fmap (getListOfFiles.(Data.Text.unpack).fromJust) $ lookupGetParam "dirpath"
                     getJsonRepForFiles files

The function which gets list of files:

-- This eliminates the hidden files from the results
getListOfFiles::FilePath -> IO (Either IOException [FilePath])
getListOfFiles fpath = try (fmap (filter $ not.isHiddenFile) $  FS.getDirectoryContents fpath)::IO (Either IOException [FilePath])

The function which gets JSON representation of the files in the directory:

getJsonRepForFiles::Monad m => (Either IOException [FilePath]) -> m Value
getJsonRepForFiles (Left e) = returnJson $ "An error occurred" ++ show e
getJsonRepForFiles (Right files) = returnJson files

Note that type of getInfoOfDirR is Handler Value I am implementing this in Haskell's Yesod framework. I am new to Haskell.. I understand somewhat why I am getting the error. But I am not able to fix it. Please help. Thanks in Advance.

Upvotes: 1

Views: 72

Answers (1)

ryachza
ryachza

Reputation: 4540

I think the issue is that getListOfFiles returns a value of type IO, and by using it with fmap you are creating a Handler (IO _), and the binding in the do block only unwraps the Handler level.

You could try joining the two levels of the fmap result, like:

files <- join $ fmap (liftIO. ...

Or move the getListOfFiles call outside the fmap application, like:

files <- liftIO . getListOfFiles =<< (fmap ...)

Upvotes: 2

Related Questions