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.  parsec question (Michael Mossey)
   2. Re:  parsec question (Magnus Therning)
   3. Re:  parsec question (David Virebayre)
   4. Re:  parsec question (Michael Mossey)
   5. Re:  parsec question (Michael Mossey)
   6. Re:  parsec question (David Virebayre)
   7. Re:  parsec question (Stephen Tetley)
   8.  Re: parsec question (Christian Maeder)
   9. Re:  Re: Enforcing Monad Laws (Ozgur Akgun)


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

Message: 1
Date: Sun, 18 Jul 2010 20:36:23 -0700
From: Michael Mossey <[email protected]>
Subject: [Haskell-beginners] parsec question
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

data Command = Play Int [Int]
              | Jump Int

-- I want to parse a string that will have any of the following forms
-- and turn it into Command
--  "p"   - Produces "Play 0 []"
--  "p v55" - Produces "Play 55 []"
--  "p c123" - Produces "Play 0 [1,2,3]"
--  "p v13 c12" - Produces "Play 13 [1,2]"

-- In other words the p command can have two kinds of arguments, "v"
-- and "c", and there are defaults for the case that no argument is
-- supplied.
-- So it's going to look something like

play :: Parser Command
play = do char 'p'
           vResult <- .. maybe a v, otherwise supply default value 0
           cResult <- .. maybe a c ..
           (could the v and c be put in either order?)
           return $ Play vResult cResult


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

Message: 2
Date: Mon, 19 Jul 2010 07:25:09 +0100
From: Magnus Therning <[email protected]>
Subject: Re: [Haskell-beginners] parsec question
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset="utf-8"

On 19/07/10 04:36, Michael Mossey wrote:
> data Command = Play Int [Int]
>              | Jump Int
> 
> -- I want to parse a string that will have any of the following forms
> -- and turn it into Command
> --  "p"   - Produces "Play 0 []"
> --  "p v55" - Produces "Play 55 []"
> --  "p c123" - Produces "Play 0 [1,2,3]"
> --  "p v13 c12" - Produces "Play 13 [1,2]"
> 
> -- In other words the p command can have two kinds of arguments, "v"
> -- and "c", and there are defaults for the case that no argument is
> -- supplied.
> -- So it's going to look something like
> 
> play :: Parser Command
> play = do char 'p'
>           vResult <- .. maybe a v, otherwise supply default value 0
>           cResult <- .. maybe a c ..
>           (could the v and c be put in either order?)
>           return $ Play vResult cResult

This isn't really an answer, but more of a suggestion on how to approach
parsing problems.

I tend to split things until I get down to easily handled stuff.  In
this case
I'd probably write the following functions:

 1. Parser for strings like "v55" and "v13": result type Parser Int
 2. Parser for strings like "c123" and "c12": result type Parser [Int]
 3. Parser combining 1 and 2: result type Parser (Int, [Int])
 4. Parser requiring a string starting with 'p ', combined with 3:
result type
    Parser Command

/M

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

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

Message: 3
Date: Mon, 19 Jul 2010 08:36:52 +0200
From: David Virebayre <[email protected]>
Subject: Re: [Haskell-beginners] parsec question
To: Michael Mossey <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=UTF-8

On Mon, Jul 19, 2010 at 5:36 AM, Michael Mossey <[email protected]> wrote:

> play :: Parser Command
> play = do char 'p'
>          vResult <- .. maybe a v, otherwise supply default value 0

A hint: The function "option" should be useful to you.

David.


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

Message: 4
Date: Mon, 19 Jul 2010 00:32:41 -0700
From: Michael Mossey <[email protected]>
Subject: Re: [Haskell-beginners] parsec question
To: haskellbeginners <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=UTF-8; format=flowed



Magnus Therning wrote:
> 
> This isn't really an answer, but more of a suggestion on how to approach
> parsing problems.
> 
> I tend to split things until I get down to easily handled stuff.  In
> this case
> I'd probably write the following functions:
> 
>  1. Parser for strings like "v55" and "v13": result type Parser Int
>  2. Parser for strings like "c123" and "c12": result type Parser [Int]
>  3. Parser combining 1 and 2: result type Parser (Int, [Int])
>  4. Parser requiring a string starting with 'p ', combined with 3:
> result type
>     Parser Command

That makes sense.

Mike


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

Message: 5
Date: Mon, 19 Jul 2010 00:41:01 -0700
From: Michael Mossey <[email protected]>
Subject: Re: [Haskell-beginners] parsec question
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Here's what I eventually came up with. I decided to make a function 
parseArg that can parse either "v" args or "c" args, and use

sepBy parseArg space

to parse all the args on the command line. I created the algebraic type 
Arg to express both kinds of args, which I call Verts and Chans, so that 
parseArg can have the signature

parseArg :: Parser Arg

and parsing the whole command line:

parseArgs :: Parser [Arg]

Then I grab the first Verts and first Chans from the resulting list, and 
ignore the other ones (if any others are present). I use fromMaybe to 
supply a default value.




data Command = Forward Int
              | Backward Int
              | Jump Int
              | Play Int [Int]
              | Quit
                deriving (Show)

data Arg = Verts Int
          | Chans [Int]
            deriving (Show)

integer :: Parser Int
integer = do ds <- many1 digit
              return (read ds)

digitList :: Parser [Int]
digitList = do d <- digit
                remainder <- digitList
                return $ read [d] : remainder
             <|>
             return []

-- Parse an argument for the p command.
-- Note that so-called "v" args are now just bare integers.
-- "c" args are still prefaced with a "c"
parseArg :: Parser Arg
parseArg = do fmap Verts integer
            <|>
            do char 'c'
               fmap Chans digitList

parseArgs :: Parser [Arg]
parseArgs = sepBy parseArg space

parseP :: Parser Command
parseP = (do many space
              -- Zero or more arguments may be present.
              -- We will consider at most one "v" argument
              -- and at most one "c" argument. There are
              -- default values for the "V" and "C" arguments
              -- when none are present.
              args <- parseArgs
              let vArgs = [i | Verts i <- args]
                  cArgs = [c | Chans c <- args]
                  singleV = fromMaybe 1 (listToMaybe vArgs)
                  singleC = fromMaybe [] (listToMaybe cArgs)
              return $ Play singleV singleC)
          <|>
            (return $ Play 1 [])


parseCommand :: Parser Command
parseCommand   = do char 'j'
                     fmap Jump integer
                  <|>
                  do char 'f'
                     fmap Forward (option 1 integer)
                  <|>
                  do char 'b'
                     fmap Backward (option 1 integer)
                  <|>
                  do char 'p'
                     parseP
                  <|>
                  do char 'q'
                     return Quit


runParse :: String -> Either String Command
runParse s = case parse parseCommand "" s of
   Left err -> Left $ show err
   Right x  -> Right x



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

Message: 6
Date: Mon, 19 Jul 2010 10:14:14 +0200
From: David Virebayre <[email protected]>
Subject: Re: [Haskell-beginners] parsec question
To: Michael Mossey <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=UTF-8

On Mon, Jul 19, 2010 at 9:41 AM, Michael Mossey <[email protected]> wrote:
> digitList :: Parser [Int]
> digitList = do d <- digit
>               remainder <- digitList
>               return $ read [d] : remainder
>            <|>
>            return []

I would write


digitList :: Parser [Int]
digitList = do
  l <- many digit
  let l' = map ( read    -- read the string
               . (: [])  -- convert the digit from a char to a string
so I can "read" it
               ) l
  return l'


That can be shortened to :

digitList :: Parser [Int]
digitList = map ( read.(:[])) `fmap` many digit

David.


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

Message: 7
Date: Mon, 19 Jul 2010 10:40:13 +0100
From: Stephen Tetley <[email protected]>
Subject: Re: [Haskell-beginners] parsec question
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Parsec has the CharParser - /integer/ - to avoid "many1 digit" and the like.

You have to instantiate a TokenParser to use it - but for all but
simplest parser the effort pays for itself.




On 19 July 2010 09:14, David Virebayre <[email protected]> wrote:


>
> That can be shortened to :
>
> digitList :: Parser [Int]
> digitList = map ( read.(:[])) `fmap` many digit
>


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

Message: 8
Date: Mon, 19 Jul 2010 11:44:41 +0200
From: Christian Maeder <[email protected]>
Subject: [Haskell-beginners] Re: parsec question
To: Michael Mossey <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Michael Mossey schrieb:
> Here's what I eventually came up with. I decided to make a function
> parseArg that can parse either "v" args or "c" args, and use
> 
> sepBy parseArg space

You may want to reject duplicate v or c args rather than to discard them
silently.

You can do so by checking the list before returning "Play singleV
singleC" and use the "fail" or "unexpected" parser for non-proper lists.

C.

> 
> to parse all the args on the command line. I created the algebraic type
> Arg to express both kinds of args, which I call Verts and Chans, so that
> parseArg can have the signature
> 
> parseArg :: Parser Arg
> 
> and parsing the whole command line:
> 
> parseArgs :: Parser [Arg]
> 
> Then I grab the first Verts and first Chans from the resulting list, and
> ignore the other ones (if any others are present). I use fromMaybe to
> supply a default value.
> 
> 
> 
> 
> data Command = Forward Int
>              | Backward Int
>              | Jump Int
>              | Play Int [Int]
>              | Quit
>                deriving (Show)
> 
> data Arg = Verts Int
>          | Chans [Int]
>            deriving (Show)
> 
> integer :: Parser Int
> integer = do ds <- many1 digit
>              return (read ds)
> 
> digitList :: Parser [Int]
> digitList = do d <- digit
>                remainder <- digitList
>                return $ read [d] : remainder
>             <|>
>             return []
> 
> -- Parse an argument for the p command.
> -- Note that so-called "v" args are now just bare integers.
> -- "c" args are still prefaced with a "c"
> parseArg :: Parser Arg
> parseArg = do fmap Verts integer
>            <|>
>            do char 'c'
>               fmap Chans digitList
> 
> parseArgs :: Parser [Arg]
> parseArgs = sepBy parseArg space
> 
> parseP :: Parser Command
> parseP = (do many space
>              -- Zero or more arguments may be present.
>              -- We will consider at most one "v" argument
>              -- and at most one "c" argument. There are
>              -- default values for the "V" and "C" arguments
>              -- when none are present.
>              args <- parseArgs
>              let vArgs = [i | Verts i <- args]
>                  cArgs = [c | Chans c <- args]
>                  singleV = fromMaybe 1 (listToMaybe vArgs)
>                  singleC = fromMaybe [] (listToMaybe cArgs)
>              return $ Play singleV singleC)
>          <|>
>            (return $ Play 1 [])
> 
> 
> parseCommand :: Parser Command
> parseCommand   = do char 'j'
>                     fmap Jump integer
>                  <|>
>                  do char 'f'
>                     fmap Forward (option 1 integer)
>                  <|>
>                  do char 'b'
>                     fmap Backward (option 1 integer)
>                  <|>
>                  do char 'p'
>                     parseP
>                  <|>
>                  do char 'q'
>                     return Quit
> 
> 
> runParse :: String -> Either String Command
> runParse s = case parse parseCommand "" s of
>   Left err -> Left $ show err
>   Right x  -> Right x
> 


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

Message: 9
Date: Mon, 19 Jul 2010 11:05:10 +0100
From: Ozgur Akgun <[email protected]>
Subject: Re: [Haskell-beginners] Re: Enforcing Monad Laws
To: Jorden M <[email protected]>
Cc: Heinrich Apfelmus <[email protected]>,
        [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="utf-8"

On 4 July 2010 16:41, Jorden M <[email protected]> wrote:

> On Sun, Jul 4, 2010 at 11:16 AM, Daniel Fischer
> <[email protected]> wrote:
> > On Sunday 04 July 2010 16:05:48, Jorden M wrote:
> >> > Now that I've had a really short look at Axioms, I think the Haskell
> >> > equivalent would be QuickCheck properties. After all, Axioms are not
> >> > enforced by the compiler, their only effect is documentation. Granted,
> >> > they
> >>
> >> Really? I thought they were.
> >>
> >
> > I think that's not even possible in general.
>
> It would equate to solving the Halting Problem, I suppose.


Nope, it would just take long (ok, very long) to compute. Halting problem is
undecidable in general.

-- 
Ozgur Akgun
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20100719/732a1b51/attachment.html

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

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


End of Beginners Digest, Vol 25, Issue 42
*****************************************

Reply via email to