
http://lpaste.net/1333635401797074944 is one way to use gunfold.
A few years ago, gunfold was error for Data.Map. If there were other
abstract data types that had gunfold = error "gunfold", generating a
VarE/ConE would be better because the failure would be at compile time
instead of at run time.
Adam
On Tue, May 5, 2015 at 12:18 PM, Edward Z. Yang
Hello Michael,
The Data instance for Map is a very interesting one indeed. Honestly, I really hate this instance, and I really hate generating a VarE, in part because there is no guarantee that fromList is defined in the same module as the type definition.
But it gives a valuable clue about how dataToQa: maybe it's wrong for us to try to directly make names based on the Constr information that is given to us: instead, the generate TH code should be a call to /gunfold/ (with TH lifting the Constr). Of course, this would be even more inefficient, but maybe the optimizer can figure it out. Unfortunately, I don't actually know how to encode an arbitrary constructor invocation indirected through Data.
Edward
Excerpts from Michael Sloan's message of 2015-04-18 12:50:39 -0700:
+1 to liftData
Removing 'Lift' altogether definitely isn't the way to go, though. As Richard points out, we want to be able to lift more than just ADTs. Also ADTs which hide their implementation can have either opaque Data instances, no Data instance, or Data instances which involve using functions for constructors.
An example of the latter is Data.Map.Map's Data instance, which uses 'fromList' as a constructor. This results in $(dataToExpQ (\_ -> Nothing) (fromList [(1,2)])) causing the compiletime error "Illegal data constructor name: ‘fromList’".
I think 'dataToExpQ' and related functions should be modified to handle this case. It should be rather easy - if the constructor Name is lowercase, generate a 'VarE' instead of a 'ConE'. I suppose this is a separate proposal, but it came up when thinking about this proposal.
-Michael
On Fri, Apr 17, 2015 at 4:21 AM, Edward Z. Yang
wrote: I propose adding the following function to Language.Haskell.TH:
-- | 'liftData' is a variant of 'lift' in the 'Lift' type class which -- works for any type with a 'Data' instance. liftData :: Data a => a -> Q Exp liftData = dataToExpQ (const Nothing)
I don't really know which submodule this should come from; since it uses 'dataToExpQ', you might put it in Language.Haskell.TH.Quote but arguably 'dataToExpQ' doesn't belong in this module either, and it only lives there because it is a useful function for defining quasiquoters and it was described in the quasiquoting paper.
I might propose getting rid of the 'Lift' class entirely, but you might prefer that class since it doesn't go through SYB (and have the attendant slowdown).
This mode of use of 'dataToExpQ' deserves more attention.
Discussion period: 1 month
Cheers, Edward _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries