Reputation: 3662
I want a sorted list of files from a directory. How do I apply the sort
function to a list with IO
monad?
import System.Directory
import Data.List
sortedFiles :: FilePath -> IO [FilePath]
sortedFiles path = do
files <- getDirectoryContents "."
return sort files -- this does not work
Upvotes: 0
Views: 592
Reputation: 4906
Others already pointed to the lack of parens.
But here's a shorter and more readable version:
import System.Directory
import Data.List
import Control.Applicative
sortedFiles :: FilePath -> IO [FilePath]
sortedFiles = sort <$> getDirectoryContents
Upvotes: 3
Reputation: 1936
The original problem is just lack of parentheses, as currently return
is being applied to two arguments (sort
and files
), just fix that up:
sortedFiles path = do
files <- getDirectoryContents "."
return (sort files)
If you want you can fmap
the sort function over the directory contents. It kind of has a nice, direct feel to it, basically lifting the sort function up into the IO monad:
sortedFiles path = sort `fmap` getDirectoryContents path
Upvotes: 8
Reputation: 27023
The return
function doesn't take two arguments. (There's an exception to this, but it's not important for beginners - it doesn't do anything like what you'd expect.) This is because return
is a function, not syntax. All the standard syntax rules for functions apply to it. You want to pass return the result of sort files
, but that's not what the syntax you're using says to do.
You want either return (sort files)
or return $ sort files
.
The two are exactly equivalent. The latter is slightly more idiomatic Haskell. Most people prefer using the $
operator to using parentheses, when both are equivalently readable.
Upvotes: 4