Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  Reading Multiple Files and Iterate Function  Application
      (Daniel Fischer)
   2. Re:  Memory tuning (Daniel Fischer)
   3. Re:  Reading Multiple Files and Iterate Function  Application
      (Lorenzo Isella)
   4.  Problem in Gtk2Hs/Glade (Tom Hobbs)


----------------------------------------------------------------------

Message: 1
Date: Mon, 11 Oct 2010 17:21:41 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Reading Multiple Files and Iterate
        Function        Application
To: [email protected]
Cc: Lorenzo Isella <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-1"

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


------------------------------

Message: 2
Date: Mon, 11 Oct 2010 17:54:14 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Memory tuning
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="utf-8"

On Monday 11 October 2010 16:14:11, Thorsten Hater wrote:
> Not only is the actual memory consumption quite high, but the
> GC/computation ratio is almost 1:1.

You construct a largish map (about 350000 entries), doing a lot (more than 
a million) of insertWith's.
That means frequent rebalancing (for new circumferences) and many updates 
of already present values (which in all likelihood are heap allocated 
Ints), both give the garbage collector a lot of work. Further, you 
construct a lot of lists, which need to be GCed too.
Also, the memory overhead of Maps is nontrivial, I think five or six words 
per item, so a Map Int Int needs about size*8(or 7)*sizeof(Int) bytes.

You can reduce the GC time by specifying a larger allocation area (e.g.
+RTS -A16M -RTS, the default size is 512K) thus making GC less frequent.

> I assume that there is something to be done regarding strictness,

Nothing obvious.
But for the computation pattern you use, since the ratio of possible values 
to occurring values is not too high, using accumArray (on an Unboxed array) 
is far better.

> but a series of experiments with
> BangPatterns return no yields at all (using foldr instead of foldl'
> produces stack overflow)

Yes, using foldr with insert(With)s into Maps is a Bad Idea™


------------------------------

Message: 3
Date: Mon, 11 Oct 2010 18:06:50 +0200
From: Lorenzo Isella <[email protected]>
Subject: Re: [Haskell-beginners] Reading Multiple Files and Iterate
        Function        Application
To: Daniel Fischer <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

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



------------------------------

Message: 4
Date: Mon, 11 Oct 2010 17:19:24 +0100
From: Tom Hobbs <[email protected]>
Subject: [Haskell-beginners] Problem in Gtk2Hs/Glade
To: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Hi all,

I playing around with simple cell automaton (Conway's Game Of Life).
I've got working code which prints everything out nicely to the
terminal, I'm trying to wrap everything in a nice GUI using Glade and
Gtk2Hs.

In order to create my world, I have a function defined as;

makeWorld :: Int -> [(Int,Int)]

Which accepts an Int, representing the size of the world, then then
outs the world itself - note the world is always assumed to be square.
 The list contains pairs such that the first element of the pair is
the index (such as for an array) and the second is the value at that
position.  For right or wrong, that's how my (working) Game Of Life
has been implemented.  The problem comes in the Gtk2Hs code...

main = do
  initGUI
  Just xml <- xmlNew "gameOfLife.glade"
  window <- xmlGetWidget xml castToWindow "mainWindow"
  onDestroy window mainQuit
  quitButton <- xmlGetWidget xml castToButton "quitButton"
  onClicked quitButton $ do
    widgetDestroy window
  setWorldSize <- xmlGetWidget xml castToButton "setWorldSize"
  sizeBox <- xmlGetWidget xml castToEntry "worldSize"
  onClicked setWorldSize $ do
    canvas <- xmlGetWidget xml castToDrawingArea "world"
    let size = (read (get sizeBox entryText) :: Int)
    cellworld <- makeWorld size
    printWorld cellworld
  widgetShowAll window
  mainGUI

The above function does not compile under GHC because;

gameOfLife.hs:27:20:
Couldn't match expected type `String'
against inferred type `IO String'
In the first argument of `read', namely `(get sizeBox entryText)'
In the expression: (read (get sizeBox entryText) :: Int)
In the definition of `size':
size = (read (get sizeBox entryText) :: Int)

gameOfLife.hs:28:2:
Couldn't match expected type `[(Int, Int)]'
against inferred type `IO (Int, Int)'
In a stmt of a 'do' expression: cellworld <- makeWorld size
In the second argument of `($)', namely
`do { canvas <- xmlGetWidget xml castToDrawingArea "world";
let size = (read (get sizeBox entryText) :: Int);
cellworld <- makeWorld size;
printWorld cellworld }'
In a stmt of a 'do' expression:
onClicked setWorldSize
$ do { canvas <- xmlGetWidget xml castToDrawingArea "world";
let size = (read (get sizeBox entryText) :: Int);
cellworld <- makeWorld size;
printWorld cellworld }

It seems to be complaining about the call to my makeWorld function,
although I do not understand why that should be.  The line number
which GHC complains about does correspond to the "cellworld <-
makeWorld size" line in my main function.

I've not yet worked out how to draw my world in the GUI, the
"printWorld" function mentioned above just spills the world out to the
termainal for now.

Does anyone have any ideas?

Many thanks,

Tom


------------------------------

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 28, Issue 20
*****************************************

Reply via email to