Dealing with IO vs pure code in haskell?

Your second, specific, problem is with the types of your functions. However, your first issue (not really a type thing) is the do statement in getFileNameAndSize While do is used with monads, it's not a monadic panacea; it's actually implemented as some simple translation rules The Cliff's Notes version (which isn't exactly right, but is close enough) is: do a ≡ x do a ; be ; c ≡ a >> do be ; c do x >= \x -> do be ; c In other words getFileNameAndSize is equivalent to the version without the do block, and so you can get rid of the do This leaves you with getFileNameAndSize fname = (fname, withFile fname ReadMode hFileSize) We can find the type for this: since fname is the first argument to withFile it has type FilePath and hFileSize returns an IO Integer so that's the type of withFile Thus, we have getFileNameAndSize :: FilePath -> (FilePath, IO Integer) This may or may not be what you want; you might instead want FilePath -> IO (FilePath,Integer) To change it, you can write any of getFileNameAndSize_do fname = do size ))`, which is a synonym for fmap. GetFileNameAndSize_fmap2 fname = ((,) fname) withFile fname ReadMode hFileSize -- With {-# LANGUAGE TupleSections #-} at the top of the file getFileNameAndSize_ts fname = (fname,) withFile fname ReadMode hFileSize Next, as KennyTM pointed out, you have fileNames IO FilePath you need to give it an argument.( e.

G getFilesWithSizes dir = do fileNames (a -> m b) -> a -> m be and so mapM getFileNameAndSize is ill-typed. You want getFileNameAndSize :: FilePath -> IO (FilePath,Integer) like I implemented above Finally, we need to fix your last line. First of all, although you don't give it to us cmpFilesBySize is presumably a function of type (FilePath, Integer) -> (FilePath, Integer) -> Ordering comparing on the second element.

This is really simple, though: using Data.Ord. Comparing :: Ord a => (b -> a) -> be -> be -> Ordering you can write this comparing snd which has type Ord be => (a, b) -> (a, b) -> Ordering Second, you need to return your result wrapped up in the IO monad rather than just as a plain list; the function return :: Monad m => a -> m a will do the trick Thus, putting this all together, you'll get import System. IO (FilePath, withFile, IOMode(ReadMode), hFileSize) import System.

Directory (getDirectoryContents) import Control. Applicative (()) import Data. List (sortBy) import Data.

Ord (comparing) getFileNameAndSize :: FilePath -> IO (FilePath, Integer) getFileNameAndSize fname = ((,) fname) withFile fname ReadMode hFileSize getFilesWithSizes :: FilePath -> IO (FilePath,Integer) getFilesWithSizes dir = do fileNames f b) -> a -> f (a,b) preservingF f x = (x,) f x -- Or liftM2 () (,), but I am not entirely sure why. FileSize :: FilePath -> IO Integer fileSize fname = withFile fname ReadMode hFileSize getFilesWithSizes :: FilePath -> IO (FilePath,Integer) getFilesWithSizes = return . SortBy (comparing snd) b) -> a -> (a,b) should be in a package somewhere, but I've been unable to find either.

Your second, specific, problem is with the types of your functions. However, your first issue (not really a type thing) is the do statement in getFileNameAndSize. While do is used with monads, it's not a monadic panacea; it's actually implemented as some simple translation rules.

The Cliff's Notes version (which isn't exactly right, but is close enough) is: do a ≡ x do a ; be ; c ... ≡ a >> do be ; c ... do x >= \x -> do be ; c ... In other words, getFileNameAndSize is equivalent to the version without the do block, and so you can get rid of the do. This leaves you with getFileNameAndSize fname = (fname, withFile fname ReadMode hFileSize) We can find the type for this: since fname is the first argument to withFile, it has type FilePath; and hFileSize returns an IO Integer, so that's the type of withFile .... Thus, we have getFileNameAndSize :: FilePath -> (FilePath, IO Integer). This may or may not be what you want; you might instead want FilePath -> IO (FilePath,Integer).

To change it, you can write any of getFileNameAndSize_do fname = do size ))`, which is a synonym for fmap. GetFileNameAndSize_fmap2 fname = ((,) fname) withFile fname ReadMode hFileSize -- With {-# LANGUAGE TupleSections #-} at the top of the file getFileNameAndSize_ts fname = (fname,) withFile fname ReadMode hFileSize Next, as KennyTM pointed out, you have fileNames IO FilePath, you need to give it an argument. (e.g. GetFilesWithSizes dir = do fileNames (a -> m b) -> a -> m b, and so mapM getFileNameAndSize is ill-typed.

You want getFileNameAndSize :: FilePath -> IO (FilePath,Integer), like I implemented above. Finally, we need to fix your last line. First of all, although you don't give it to us, cmpFilesBySize is presumably a function of type (FilePath, Integer) -> (FilePath, Integer) -> Ordering, comparing on the second element.

This is really simple, though: using Data.Ord. Comparing :: Ord a => (b -> a) -> be -> be -> Ordering, you can write this comparing snd, which has type Ord be => (a, b) -> (a, b) -> Ordering. Second, you need to return your result wrapped up in the IO monad rather than just as a plain list; the function return :: Monad m => a -> m a will do the trick.

Thus, putting this all together, you'll get import System. IO (FilePath, withFile, IOMode(ReadMode), hFileSize) import System. Directory (getDirectoryContents) import Control.

Applicative (()) import Data. List (sortBy) import Data. Ord (comparing) getFileNameAndSize :: FilePath -> IO (FilePath, Integer) getFileNameAndSize fname = ((,) fname) withFile fname ReadMode hFileSize getFilesWithSizes :: FilePath -> IO (FilePath,Integer) getFilesWithSizes dir = do fileNames f b) -> a -> f (a,b) preservingF f x = (x,) f x -- Or liftM2 () (,), but I am not entirely sure why.

FileSize :: FilePath -> IO Integer fileSize fname = withFile fname ReadMode hFileSize getFilesWithSizes :: FilePath -> IO (FilePath,Integer) getFilesWithSizes = return . SortBy (comparing snd) a -> (a,b), should be in a package somewhere, but I've been unable to find either.

Thanks, great answer, I still understand very little I guess because I understand 40% of it, but it solved the problem ;) – Drakosha May 30 '10 at 5:30 Glad I could help. Is there anything in particular you don't get? A lot of stuff towards the end is more something I think you might want to look at/learn, rather than as something I think you ought to already know.

– Antal S-Z May 31 '10 at 20:57.

GetDirectoryContents is a function. You should supply an argument to it, e.g. FileNames (FilePath, IO Integer), as you can check from ghci: Prelude> :m + System.IO Prelude System. IO> let getFileNameAndSize fname = do (fname, (withFile fname ReadMode hFileSize)) Prelude System.

IO> :t getFileNameAndSize getFileNameAndSize :: FilePath -> (FilePath, IO Integer) But mapM requires the input function to return an IO stuff: Prelude System.IO> :t mapM mapM :: (Monad m) => (a -> m b) -> a -> m be -- # ^^^^^^^^ You should change its type to FilePath -> IO (FilePath, Integer) to match the type. GetFileNameAndSize fname = do fsize.

1 Thanks, great answer – Drakosha May 30 '10 at 5:29.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions