[Haskell-cafe] Re: I want my free (and good looking) parser!

Slavomir Kaslev 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
> Text.ParserCombinators.Parsec.Token)
>
> 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
>>>> expamle.]
>>>>
>>>> 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.
>>>>
>>>> Cheers!
>>>>
>>
>>
>>
>

-- 
Slavomir Kaslev


More information about the Haskell-Cafe mailing list