ollef / Earley

Parsing all context-free grammars using Earley's algorithm in Haskell.
BSD 3-Clause "New" or "Revised" License
361 stars 24 forks source link

add IsString instance #23

Closed sboosali closed 8 years ago

sboosali commented 8 years ago

like:

instance (IsString t, Eq t, a ~ t) => IsString (Prod r e t a) where
 fromString s = Terminal (== t) (pure id)

and/or even:

instance (IsString t) => IsList (Prod r e t a) where
 type Item (Prod r e t a) = Prod r e t a
 fromList ps = Alts ps (pure id)
 toList = \case
  Alts ps f -> fmap (f <*>) ps
  p -> [p]

(away from my computer, haven't type checked)

The IsString instance increases the readability of the DSL, has a single simple implemention (and thus avoids forcing orphans on users), and doesn't confuse user when they don't enable OverloadStrings.

sboosali commented 8 years ago

also see http://chrisdone.com/posts/haskell-constraint-trick

ollef commented 8 years ago

This idea improves the syntax for certain kinds of grammars. I like it! One complication is that there are several useful instances and it's not obvious which one to choose. Modulo constraint tricks, these are:

IsString t => IsString (Prod r e t t) -- (1) For grammars working on String-likes (what you propose)
IsString t => IsString (Prod r e Char t) -- (2.a) For grammars working on Chars
IsString (Prod r e Char ()) -- (2.b) Same as above but probably more useful (instance resolution problems)

Basically, (1) is for grammars that work on tokenised inputs, and (2) for grammars working directly on Chars. (1) looks more useful to me, but maybe someone has another opinion?

I suppose it's better to please some than to please no-one though, so I would welcome a pull request.