[Haskell-cafe] Re: I want my free (and good looking) parser!
slavomir.kaslev at gmail.com
Mon Oct 6 16:28:46 EDT 2008
On Mon, Oct 6, 2008 at 9:36 PM, Christian Maeder
<Christian.Maeder at dfki.de> wrote:
> import Text.ParserCombinators.Parsec
> freeParser :: (Enum a, Bounded a, Show a) => Parser a
> freeParser = choice $ map (\ a -> try $ do
> string $ show a
> notFollowedBy (alphaNum <|> char '_')
> return a) [minBound .. maxBound]
This is exactly what I needed. Though I still don't quite understand
why this works and mine doesn't.
> I see not need for extensions. (And I don't like
> Where did you get enumAll from?
Mine definition of enumAll was equivаlent to [minBound .. maxBound]:
enumAll :: (Bounded a, Enum a) => [a]
еnumAll = enumFromTo minBound maxBound
> The type of the Parser must be deducible from the context (or given by a
> type annotation).
> Cheers C.
> Slavomir Kaslev wrote:
>> On Mon, Oct 6, 2008 at 8:07 PM, Christian Maeder
>> <Christian.Maeder at dfki.de> wrote:
>>> Slavomir Kaslev wrote:
>>>>> freeParser = freeParser' minBound
>>>>> where enumAll' :: (Bounded a, Enum a) => a -> [a]
>>>>> enumAll' _ = enumAll
>>>>> freeParser' :: (Enum a, Bounded a, Show a, Read a) => a -> Parser a
>>>>> freeParser' x = liftM read $ choice (map (string . show) (enumAll' x))
>>> 1. I would use an explicit function argument instead of "Show" to allow
>>> strings starting with lower case.
>> You are right. But that was not the problem. The problem was that I
>> wrestled with Haskell's type system quite a bit to make freeParser
>> work. What I want to write is
>> freeParser :: (Enum a, Bounded a, Show a, Read a) => Parser a
>> freeParser = liftM read $ choice (map (string . show) enumAll)
>> but it doesn't compile. How can I make this piece code work?
>>> 2. Calling read after parsing looks stupid. Just return the value shown
>>> as parser result (within map).
>> Good point. It is silly =-)
>>> 3. Instead of the "string" parser, it should be checked if a further
>>> alphaNum or '_' follows (for the longest match). And don't forget "try"!
>> Sure. I actually use Parsec's reserved, which is kind enough to manage
>> all this stuff for me.
>>> Cheers Christian
>>>> [Actually, in my code I use reserved' (reserved' x = reserved x >> return x)
>>>> instead of string, where reserved is from Parsec's builtin tokenizer (which does
>>>> some neat things behind the curtains). Here string is used just to
>>>> illustrate the
>>>> The problem is that freeParser, although useful, is far from elegant. It's
>>>> something that I came up with by trial and error. In short: it's a hack.
>>>> I would like to hear your suggestions about how it can be beautified.
>>>> Thank you in advance.
More information about the Haskell-Cafe