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
*****************************************