illissius at gmail.com
Tue Oct 4 15:58:15 CEST 2011
On Tue, Oct 4, 2011 at 3:25 PM, Yitzchak Gale <gale at sefer.org> wrote:
> George Giorgidze wrote:
>> My second proposal is to introduce the
>> OverloadedLists extension that overloads
>> list literals...
> I am opposed to this proposal as stated.
> But I think that with a modification,
> it can not only be improved, but also solve
> the problems with the current OverloadedStrings
> OverloadedStrings - and George's unmodified
> proposal - change compile time errors into run
> time errors. Literals with hard-to-find problems
> are accepted by the compiler and become
> _|_ at run time.
> An example of the problem: the xml-types
> package has an IsString instance for
> Name. The fromString method parses
> XML namespaces from XML names and
> calls error if the parse fails. Without the
> extension, one would specify the parts using
> constructors; that is wordy and awkward but
> checked at compile time. A quasi-quoter
> could be defined, but that syntax would still
> be far less convenient in practice than
> string literals.
> I agree that we need a way of allowing literals
> to have some flexibility in their types. But there
> should be a way for overloading to work
> at compile time, i.e. more like a quasi-quoter,
> when needed.
> Of course, "quasi-quoter" overloading can also
> just create an expression that applies a coercion function
> at run time. So in that sense, "quasi-quoter" overloading
> is more general than ad-hoc-polymorphism overloading.
> In all of George's examples fromList happens to be total,
> so there isn't an issue having it happen at run time. But if we
> make this generally available, you can be certain that
> it will cause problems later on. Just as with IsString,
> people will not be able to resist the nice syntax, and
> they will define fromList implementations that are partial.
> Here is a tentative modification of George's proposal:
> class IsList l where
> type Item l
> fromList :: [Item l] -> l
> listExpQ :: [ExpQ] -> ExpQ
> -- Minimal complete definition: fromList
> listExpQ = appE (varE (mkName "fromList")) . listE
listExpQ doesn't actually use the class's type variable here. You'd
have to add a dummy parameter ('l' or preferably 'Proxy l').
That said, this seems like what the Lift class was made for. Maybe:
class Lift l => IsList l where
fromList :: [Item l] -> l
and then have GHC apply the function at compile time, during the
Template Haskell phase, and then lift and splice the result. That
would resolve both your complaint about partial instances (an
exception at compile time is a compile error) and Roman's about
performance (if it results in a performance hit with some data
structures, it'll only be at compile time). I don't know if it would
work out mechanically (i.e. whether GHC's internals allow this kind of
In the spirit of "don't let the perfect be the enemy of the good"
though, I'm solidly in favor of the original proposal as it is. My
only quibble is whether it might not be better called FromList (or
FromListLiteral or ...), given that a Map Is not really a List. Since
IsString is named the same way, the question is whether consistency or
accuracy is more important.
> If the type of a list literal determines a specific instance
> of IsList at compile time, use the listExpQ from that
> instance to interpret the list literal. Otherwise, use the
> default listExpQ, which is just George's original proposal.
> An alternative would be to put listExpQ in a separate type
> class with an IsList constraint.
> IsString can similarly be extended in a backward compatible
> way to allow syntax checking at compile time. Here the
> type could be stringExpQ :: String -> ExpQ
> Numeric literals with Num and Integral can also be extended,
> though I think the problem is less common for those.
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users at haskell.org
Work is punishment for failing to procrastinate effectively.
More information about the Glasgow-haskell-users