I am trying to make a webpage that will list the contents of a given directory, but I am running into a strange problem: The code produces the desired output when I run it line by line in GHCi, but when it is executed in the running Scotty instance, it produces different (wrong) output. Here is the relevant part of the code:
serveDir :: String -> ActionM ()
serveDir p = do let path = prefix ++ p
entries <- liftIO $ getDirectoryContents path
fs <- liftIO $ filterM (doesFileExist . ((++) prefix)) entries
ds <- liftIO $ filterM (doesDirectoryExist . ((++) prefix)) entries
liftIO $ print path >> print entries >> print fs >> print ds
blaze $ renderDir fs ds
where prefix = "static/"
(that last line in the do
statement just renders it into html. this works, but the correct output never makes it to that function)
When I run each line of this function in GHCi, i get the following output:
*Main> entries <- getDirectoryContents "static/stuff"
*Main> fs <- liftIO $ filterM (doesFileExist . ((++) "static/stuff/")) entries
*Main> ds <- liftIO $ filterM (doesDirectoryExist . ((++) "static/stuff/")) entries
*Main> liftIO $ print entries >> print fs >> print ds
["..","hello","bye","someDir","."]
["hello","bye"]
["..","someDir","."]
which is what I am expecting. But when this function is run from Scotty, called as serveDir "stuff/"
, I get this output:
"static/stuff/"
["..","hello","bye","someDir","."]
[]
["..","."]
What is happening here? I know that ActionM is an instance of MonadIO, otherwise this would not compile. I am at a bit of a loss. Can somebody shed some light on this or advise? Rest of code available upon request, but I can say that I am using wai-middleware-static to allow static file requests, and other file request from this directory in other functions works.
fs <- liftIO $ filterM (doesFileExist . ((++) prefix)) entries
Should that not be (++) path
?