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:  Help with monads (I think...) (Andrew Wagner)
   2.  Baffled by Parsec (Colin Paul Adams)
   3. Re:  Baffled by Parsec (Daniel Fischer)
   4. Re:  Baffled by Parsec (Magnus Therning)
   5.  A better way? (Keith Sheppard)
   6. Re:  A better way? (Thomas Davie)
   7. Re:  A better way? (Keith Sheppard)


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

Message: 1
Date: Sat, 21 Feb 2009 08:11:16 -0500
From: Andrew Wagner <[email protected]>
Subject: Re: [Haskell-beginners] Help with monads (I think...)
To: Thomas Davie <[email protected]>
Cc: beginners <[email protected]>
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="windows-1252"

Yes, this is much more idiomatic haskell.

On Sat, Feb 21, 2009 at 4:59 AM, Thomas Davie <[email protected]> wrote:

>
> On 21 Feb 2009, at 01:30, Patrick LeBoutillier wrote:
>
> Hi all,
>
> I'm trying to implement the following simple Perl program in Haskell:
>
>  my $nb_tests = 0 ;
>
>  sub ok {
>          my $bool = shift ;
>          $nb_tests++ ;
>          print STDOUT ($bool ? "ok" : "nok") . " $nb_tests\n" ;
>  }
>
>  ok(0) ;
>  ok(1) ;
>
> The output is:
>
>  nok 1
>  ok 2
>
> I'm pretty much a Haskell newbie, but I know a bit about monads (and
> have been reading "Real World Haskell"), and I think I need to put the
> ok function must live inside some kind of state monad. My problem is
> that I also would like the ok function to perform some IO (as shown
> above, print).
>
> How is a case like this handled? Can my function live in 2 monads?
>
>
> I personally wouldn't use two monads at all for this – in fact, I'd only
> use IO in one function:
>
> main = putStr . unlines . results inputs . snd . tests $ inputs
>
> inputs = [1,2]
>
> tests = foldr (\_ (x,l) -> (not x, x:l)) (True,[])
>
> results = zipWith result
> result testN True  = "ok "  ++ show testN
> result testN False = "nok " ++ show testN
>
> Bob
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090221/c4b40170/attachment-0001.htm

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

Message: 2
Date: Sat, 21 Feb 2009 20:04:21 +0000
From: Colin Paul Adams <[email protected]>
Subject: [Haskell-beginners] Baffled by Parsec
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

The tutorials I've found don't tell me what I want to know :-(

I have lines that begin with an integer, then white-space, and then
further structure to the end-of-line.

So for a starter, could you show me how to write a parser for the
integer (returning an Int), and how to combine it with a parser for
the rest of the line (take that as written - it isn't, but I'll try to
do that myself given such a kick-start).

Thanks.
-- 
Colin Adams
Preston Lancashire


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

Message: 3
Date: Sat, 21 Feb 2009 22:10:36 +0100
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Baffled by Parsec
To: Colin Paul Adams <[email protected]>,        [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain;  charset="iso-8859-1"

Am Samstag, 21. Februar 2009 21:04 schrieb Colin Paul Adams:
> The tutorials I've found don't tell me what I want to know :-(
>
> I have lines that begin with an integer, then white-space, and then
> further structure to the end-of-line.
>
> So for a starter, could you show me how to write a parser for the
> integer (returning an Int), and how to combine it with a parser for
> the rest of the line (take that as written - it isn't, but I'll try to
> do that myself given such a kick-start).
>
> Thanks.

-- could also be Parser Int, if you don't need user-state
parseInt :: GenParser Char st Int
parseInt = do
        neg <- (char '-' >> return True) <|> (optional (char '+') >> return 
False)
        digs <- many1 digit
        let n | neg = negate $ read digs
              | otherwise = read digs
        return n

parseLine :: GenParser Char st LineStructure
parseLine = do
        -- spaces here, if there may be whitespace at the beginning of lines
        num <- parseInt
        spaces
        things <- parseRemainderOfLine
        return (combine num things)


The strategy is always the same, you write parsers for small things and 
combine their results.
Note that things are somewhat tricky if the structure you want to parse isn't 
very strict, if one of your possible parsers at some point in the parsing 
process can fail, but not immediately and you need to backtrack, you have to 
use the 'try' combinator as in

combo = (try parser1) <|> parser2

, but try is bad for performance, so use it only where it's necessary.
The latter part is notoriously difficult to identify for the inexperienced, so 
until you know parsec better, it's okay to insert a few 'try's more than 
necessary.

HTH, otherwise ask again,
Daniel



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

Message: 4
Date: Sat, 21 Feb 2009 21:07:53 +0000
From: Magnus Therning <[email protected]>
Subject: Re: [Haskell-beginners] Baffled by Parsec
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"

Colin Paul Adams wrote:
> The tutorials I've found don't tell me what I want to know :-(
> 
> I have lines that begin with an integer, then white-space, and then
> further structure to the end-of-line.
> 
> So for a starter, could you show me how to write a parser for the
> integer (returning an Int), and how to combine it with a parser for
> the rest of the line (take that as written - it isn't, but I'll try to
> do that myself given such a kick-start).

Maybe one of my old blog posts can help?

http://therning.org/magnus/archives/289

/M

-- 
Magnus Therning                        (OpenPGP: 0xAB4DFBA4)
magnus@therning.org          Jabber: magnus@therning.org
http://therning.org/magnus         identi.ca|twitter: magthe

Haskell is an even 'redder' pill than Lisp or Scheme.
     -- PaulPotts

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 197 bytes
Desc: OpenPGP digital signature
Url : 
http://www.haskell.org/pipermail/beginners/attachments/20090221/1ab208fc/signature-0001.bin

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

Message: 5
Date: Sat, 21 Feb 2009 16:35:39 -0500
From: Keith Sheppard <[email protected]>
Subject: [Haskell-beginners] A better way?
To: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Hello,

I'm new to haskell and still getting used to working with lazy
evaluation. I created a little function to calculate column widths for
a 2D list of strings (a table) by iterating through the list and
accumulating a max value for each column. My initial implementation
ran out memory for tables with many rows because of lazy evaluation
and here is how I dealt with it:

{- |
for a table, calculate the max width in characters for each column
-}
maxTableColumnWidths :: [[String]] -> [Int]
maxTableColumnWidths [] = []
maxTableColumnWidths table =
    maxTableColumnWidthsInternal table []

maxTableColumnWidthsInternal :: [[String]] -> [Int] -> [Int]
maxTableColumnWidthsInternal [] prevMaxValues = prevMaxValues
maxTableColumnWidthsInternal (row:tableTail) prevMaxValues
    | seqList prevMaxValues = undefined
    | otherwise = maxTableColumnWidthsInternal tableTail
(maxRowFieldWidths row prevMaxValues)

-- this little function is for making the list strict... otherwise
-- we run out of memory
seqList [] = False
seqList (head:tail)
    | head `seq` False = undefined
    | otherwise = seqList tail

maxRowFieldWidths :: [String] -> [Int] -> [Int]
maxRowFieldWidths row prevMaxValues =
    let colLengths = map length row
        lengthOfRow = length row
        lengthOfPrevMax = length prevMaxValues
        maxPrefixList = zipWith max colLengths prevMaxValues
    in
        if lengthOfRow == lengthOfPrevMax then
            maxPrefixList
        else if lengthOfRow > lengthOfPrevMax then
            maxPrefixList ++ (drop lengthOfPrevMax colLengths)
        else
            maxPrefixList ++ (drop lengthOfRow prevMaxValues)


This works but it isn't very pretty (maybe also inefficient?). Is
there a better way to deal with this kind of memory issue?

Thanks!
Keith


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

Message: 6
Date: Sat, 21 Feb 2009 23:29:35 +0100
From: Thomas Davie <[email protected]>
Subject: Re: [Haskell-beginners] A better way?
To: Keith Sheppard <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII; format=flowed

How about this:

maxTableColumnWidths :: [[String]] -> [Int]
maxTableColumnWidths = map (maximum . map length)

Bob


On 21 Feb 2009, at 22:35, Keith Sheppard wrote:

> Hello,
>
> I'm new to haskell and still getting used to working with lazy
> evaluation. I created a little function to calculate column widths for
> a 2D list of strings (a table) by iterating through the list and
> accumulating a max value for each column. My initial implementation
> ran out memory for tables with many rows because of lazy evaluation
> and here is how I dealt with it:
>
> {- |
> for a table, calculate the max width in characters for each column
> -}
> maxTableColumnWidths :: [[String]] -> [Int]
> maxTableColumnWidths [] = []
> maxTableColumnWidths table =
>    maxTableColumnWidthsInternal table []
>
> maxTableColumnWidthsInternal :: [[String]] -> [Int] -> [Int]
> maxTableColumnWidthsInternal [] prevMaxValues = prevMaxValues
> maxTableColumnWidthsInternal (row:tableTail) prevMaxValues
>    | seqList prevMaxValues = undefined
>    | otherwise = maxTableColumnWidthsInternal tableTail
> (maxRowFieldWidths row prevMaxValues)
>
> -- this little function is for making the list strict... otherwise
> -- we run out of memory
> seqList [] = False
> seqList (head:tail)
>    | head `seq` False = undefined
>    | otherwise = seqList tail
>
> maxRowFieldWidths :: [String] -> [Int] -> [Int]
> maxRowFieldWidths row prevMaxValues =
>    let colLengths = map length row
>        lengthOfRow = length row
>        lengthOfPrevMax = length prevMaxValues
>        maxPrefixList = zipWith max colLengths prevMaxValues
>    in
>        if lengthOfRow == lengthOfPrevMax then
>            maxPrefixList
>        else if lengthOfRow > lengthOfPrevMax then
>            maxPrefixList ++ (drop lengthOfPrevMax colLengths)
>        else
>            maxPrefixList ++ (drop lengthOfRow prevMaxValues)
>
>
> This works but it isn't very pretty (maybe also inefficient?). Is
> there a better way to deal with this kind of memory issue?
>
> Thanks!
> Keith
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners



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

Message: 7
Date: Sat, 21 Feb 2009 17:53:25 -0500
From: Keith Sheppard <[email protected]>
Subject: Re: [Haskell-beginners] A better way?
To: Thomas Davie <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Thank you for the reply, but it looks like this is a different
function. Here is the interactive output of my function vs. the one
you give (my code is in Table/IO.hs):

Prelude> :load Table.IO
*Table.IO> maxTableColumnWidths  (replicate 10 ["hello", "world"])
[5,5]
*Table.IO> let maxTableColumnWidths2 = map (maximum . map length)
*Table.IO> maxTableColumnWidths2  (replicate 10 ["hello", "world"])
[5,5,5,5,5,5,5,5,5,5]

-Keith

On Sat, Feb 21, 2009 at 5:29 PM, Thomas Davie <[email protected]> wrote:
> How about this:
>
> maxTableColumnWidths :: [[String]] -> [Int]
> maxTableColumnWidths = map (maximum . map length)
>
> Bob
>
>
> On 21 Feb 2009, at 22:35, Keith Sheppard wrote:
>
>> Hello,
>>
>> I'm new to haskell and still getting used to working with lazy
>> evaluation. I created a little function to calculate column widths for
>> a 2D list of strings (a table) by iterating through the list and
>> accumulating a max value for each column. My initial implementation
>> ran out memory for tables with many rows because of lazy evaluation
>> and here is how I dealt with it:
>>
>> {- |
>> for a table, calculate the max width in characters for each column
>> -}
>> maxTableColumnWidths :: [[String]] -> [Int]
>> maxTableColumnWidths [] = []
>> maxTableColumnWidths table =
>>   maxTableColumnWidthsInternal table []
>>
>> maxTableColumnWidthsInternal :: [[String]] -> [Int] -> [Int]
>> maxTableColumnWidthsInternal [] prevMaxValues = prevMaxValues
>> maxTableColumnWidthsInternal (row:tableTail) prevMaxValues
>>   | seqList prevMaxValues = undefined
>>   | otherwise = maxTableColumnWidthsInternal tableTail
>> (maxRowFieldWidths row prevMaxValues)
>>
>> -- this little function is for making the list strict... otherwise
>> -- we run out of memory
>> seqList [] = False
>> seqList (head:tail)
>>   | head `seq` False = undefined
>>   | otherwise = seqList tail
>>
>> maxRowFieldWidths :: [String] -> [Int] -> [Int]
>> maxRowFieldWidths row prevMaxValues =
>>   let colLengths = map length row
>>       lengthOfRow = length row
>>       lengthOfPrevMax = length prevMaxValues
>>       maxPrefixList = zipWith max colLengths prevMaxValues
>>   in
>>       if lengthOfRow == lengthOfPrevMax then
>>           maxPrefixList
>>       else if lengthOfRow > lengthOfPrevMax then
>>           maxPrefixList ++ (drop lengthOfPrevMax colLengths)
>>       else
>>           maxPrefixList ++ (drop lengthOfRow prevMaxValues)
>>
>>
>> This works but it isn't very pretty (maybe also inefficient?). Is
>> there a better way to deal with this kind of memory issue?
>>
>> Thanks!
>> Keith
>> _______________________________________________
>> Beginners mailing list
>> [email protected]
>> http://www.haskell.org/mailman/listinfo/beginners
>
>


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

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


End of Beginners Digest, Vol 8, Issue 18
****************************************

Reply via email to