[Haskell-beginners] Reading Multiple Files and Iterate Function Application

Lorenzo Isella lorenzo.isella at gmail.com
Mon Oct 11 12:06:50 EDT 2010


Thanks a lot Daniel, but I am a bit lost (up to not long ago I did not 
even know the existence of a control monad...and some unstructured 
reading did not help).
Some online research about mapM and fmap led me here
http://en.wikibooks.org/wiki/Haskell/Category_theory
and I think I am a bit astray at this point ;-)

Why does my "simple" snippet below raise a number of errors?
Cheers

Lorenzo


import Data.Ord

import Data.List

main :: IO ()

main = do

   let nums=[1,2]

   let fl = getAllLengths nums

   putStrLn "fl is, "
   print fl


filename :: Int -> FilePath
filename i = "file" ++ show i ++ ".dat"

fileLength :: FilePath -> IO Int
fileLength file = fmap length (readFile file)

getAllLengths :: [Int] -> IO [Int]
getAllLengths nums = mapM (fileLength . filename) nums



On 10/11/2010 05:21 PM, Daniel Fischer wrote:
> On Monday 11 October 2010 16:56:58, Lorenzo Isella wrote:
>> Dear All,
>> Another I/O question.
>> Let us say that you are given a list of files file1.dat,
>> file2.dat...file10.dat and so on (i.e. every file is indexed by a number
>> and every file is a single column where every entry is a string without
>> spaces).
>> In the snippet below I read file1.dat, convert it to a list and then
>> print out its length.
>> Now, how can I iterate the process on file1.dat, file2.dat and file3.dat
>> and store the lengths in a list?
>
> fileLength :: FilePath ->  IO Int
> fileLength file = fmap length (readFile file)
>
> filename :: Int ->  FilePath
> filename i = "file" ++ show i ++ ".dat"
>
> getAllLengths :: [Int] ->  IO [Int]
> getAllLengths nums = mapM (fileLength . filename) nums
>
>
> If you want something other than the character count, instead of fileLength
> use e.g.
>
> countLines :: FilePath ->  IO Int
> countLines file = fmap (length . lines) (readFile file)
>
> or whatever you're interested in.
>
> Another nice thing is often forM (from Control.Monad)
>
> forM nums $ \i ->  do
>     let filename = "file" ++ show i ++ ".dat"
>     contents<- readFile filename
>     let result = function contents
>     doSomethingOrNot
>     return result
>
>> I would like to map the file reading and following operations on the
>> list [1,2.3], but that is giving me a headache.
>> It is relatively easy to create the file name
>>
>> filename="file"++(show i)++".dat"   , for i=1,2,3
>>
>> but it the the iteration part that is giving me troubles.
>> Any suggestion is appreciated.
>> Cheers
>>
>> Lorenzo



More information about the Beginners mailing list