Re: Trees that Grow and constraints
I have updated the page, with a bit more detail and an additional plan > OK. It’s hard to keep this straight in email. Take a look at >> >> https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/Instances >> >> >> >> Please edit and improve it. >> >> Alan ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: Trees that Grow and constraints
Will do Alan On 13 November 2017 at 19:08, Simon Peyton Jones <simo...@microsoft.com> wrote: > Alan (adding Shayan and ghc-devs) > > > > OK. It’s hard to keep this straight in email. Take a look at > > https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/Instances > > > > Please edit and improve it. > > > > Simon > > > > > > *From:* Alan & Kim Zimmerman [mailto:alan.z...@gmail.com] > *Sent:* 13 November 2017 13:30 > > *To:* Simon Peyton Jones <simo...@microsoft.com> > *Subject:* Re: Trees that Grow and constraints > > > > At the moment, in GHC master, we have > > data HsOverLit p > > = OverLit { > > ol_ext :: (XOverLit p), > > ol_val :: OverLitVal, > > ol_witness :: HsExpr p} -- Note [Overloaded literal witnesses] > > > > | XOverLit > > (XXOverLit p) > > deriving instance (DataIdLR p p) => Data (HsOverLit p) > > > > And in HsExtension.hs we have an ever-growing constraint type defining > DataIdLR > > I am trying to remove the need for that. > > In the Experiment.hs file, I found that using > > data Experiment p > = Experiment { > e_ext :: (XEOverLit p), > e_val :: Int } > | XExperiment (XXOverLit p) > deriving instance Data (GhcPass 'Parsed ) => Data (Experiment (GhcPass > 'Parsed )) > deriving instance Data (GhcPass 'Renamed) => Data (Experiment (GhcPass > 'Renamed)) > deriving instance Data (GhcPass 'Typechecked) => Data (Experiment (GhcPass > 'Typechecked)) > > will compile using GHC 8.2.1, but not with GHC 8.0.2 > > > > Alan > > > > On 13 November 2017 at 15:13, Simon Peyton Jones <simo...@microsoft.com> > wrote: > > And it looks like it could work, when bootstrapping from GHC 8.2.1, but > this is still a long time away. > > > > I’m sorry, I still don’t know what “it” is that “could work”. Can you be > more precise. I think you must be suggesting some alternative to my code > below? > > > > Simon > > > > *From:* Alan & Kim Zimmerman [mailto:alan.z...@gmail.com] > *Sent:* 13 November 2017 13:09 > > > *To:* Simon Peyton Jones <simo...@microsoft.com> > *Subject:* Re: Trees that Grow and constraints > > > > Yes. > > > > If we can solve this, it means we can get rid of the DataId and ForallXXX > constraints defined in hsSyn/HsExtension.hs > > > > And also move the type family definitions to the files where they are used. > > > > I suspect that typechecking those constraint sets is adding to the GHC > compilation time, significantly > > > > And it looks like it could work, when bootstrapping from GHC 8.2.1, but > this is still a long time away. > > > > Alan > > > > On 13 November 2017 at 15:05, Simon Peyton Jones <simo...@microsoft.com> > wrote: > > That’s not a problem you are trying to solve – it’s just some code . > > > > Let me hazard a guess. You want a derived instance for > > > > Data (OverLit (GhcPass p)) > > > > But to do that of course we’ll need Data (XEOverLit (GhcPass p)). > > > > We can’t possibly have that at the time of writing the instance > declaration, because p is universally quantified. So we are stuck with > > > > instance (Data (XEOverLit (GhcPass p))) => Data (OverLit > (GhcPass p)) where… > > > > and the context gets a constraint for every extension field in OverLit, > which is painful. > > > > So we have a solution bit contexts, but it’s painful. > > > > Is that the problem you are trying to solve? > > > > Simon > > > > *From:* Alan & Kim Zimmerman [mailto:alan.z...@gmail.com] > *Sent:* 13 November 2017 13:01 > *To:* Simon Peyton Jones <simo...@microsoft.com> > > *Subject:* Re: Trees that Grow and constraints > > > > Sorry, I simplified the problem. > > The actual one I am trying to solve will be the general case, so e.g. > > type instance XEOverLit (GhcPass 'Parsed ) = RdrName > type instance XEOverLit (GhcPass 'Renamed) = Name > type instance XEOverLit (GhcPass 'Typechecked) = Id > > or more likely, modelling the existing PostTc and PostRn usages. > > And I suppose looking into using them in a single definition might work > > Alan > > > > > > On 13 November 2017 at 14:55, Simon Peyton Jones <simo...@microsoft.com> > wrote: > > Or do I misunderstand your advice? > > > > Well, you said > > Where specifying the type instance with a wild card keeps GH
RE: Trees that Grow and constraints
Alan (adding Shayan and ghc-devs) OK. It’s hard to keep this straight in email. Take a look at https://ghc.haskell.org/trac/ghc/wiki/ImplementingTreesThatGrow/Instances Please edit and improve it. Simon From: Alan & Kim Zimmerman [mailto:alan.z...@gmail.com] Sent: 13 November 2017 13:30 To: Simon Peyton Jones <simo...@microsoft.com> Subject: Re: Trees that Grow and constraints At the moment, in GHC master, we have data HsOverLit p = OverLit { ol_ext :: (XOverLit p), ol_val :: OverLitVal, ol_witness :: HsExpr p} -- Note [Overloaded literal witnesses] | XOverLit (XXOverLit p) deriving instance (DataIdLR p p) => Data (HsOverLit p) And in HsExtension.hs we have an ever-growing constraint type defining DataIdLR I am trying to remove the need for that. In the Experiment.hs file, I found that using data Experiment p = Experiment { e_ext :: (XEOverLit p), e_val :: Int } | XExperiment (XXOverLit p) deriving instance Data (GhcPass 'Parsed ) => Data (Experiment (GhcPass 'Parsed )) deriving instance Data (GhcPass 'Renamed) => Data (Experiment (GhcPass 'Renamed)) deriving instance Data (GhcPass 'Typechecked) => Data (Experiment (GhcPass 'Typechecked)) will compile using GHC 8.2.1, but not with GHC 8.0.2 Alan On 13 November 2017 at 15:13, Simon Peyton Jones <simo...@microsoft.com<mailto:simo...@microsoft.com>> wrote: And it looks like it could work, when bootstrapping from GHC 8.2.1, but this is still a long time away. I’m sorry, I still don’t know what “it” is that “could work”. Can you be more precise. I think you must be suggesting some alternative to my code below? Simon From: Alan & Kim Zimmerman [mailto:alan.z...@gmail.com<mailto:alan.z...@gmail.com>] Sent: 13 November 2017 13:09 To: Simon Peyton Jones <simo...@microsoft.com<mailto:simo...@microsoft.com>> Subject: Re: Trees that Grow and constraints Yes. If we can solve this, it means we can get rid of the DataId and ForallXXX constraints defined in hsSyn/HsExtension.hs And also move the type family definitions to the files where they are used. I suspect that typechecking those constraint sets is adding to the GHC compilation time, significantly And it looks like it could work, when bootstrapping from GHC 8.2.1, but this is still a long time away. Alan On 13 November 2017 at 15:05, Simon Peyton Jones <simo...@microsoft.com<mailto:simo...@microsoft.com>> wrote: That’s not a problem you are trying to solve – it’s just some code . Let me hazard a guess. You want a derived instance for Data (OverLit (GhcPass p)) But to do that of course we’ll need Data (XEOverLit (GhcPass p)). We can’t possibly have that at the time of writing the instance declaration, because p is universally quantified. So we are stuck with instance (Data (XEOverLit (GhcPass p))) => Data (OverLit (GhcPass p)) where… and the context gets a constraint for every extension field in OverLit, which is painful. So we have a solution bit contexts, but it’s painful. Is that the problem you are trying to solve? Simon From: Alan & Kim Zimmerman [mailto:alan.z...@gmail.com<mailto:alan.z...@gmail.com>] Sent: 13 November 2017 13:01 To: Simon Peyton Jones <simo...@microsoft.com<mailto:simo...@microsoft.com>> Subject: Re: Trees that Grow and constraints Sorry, I simplified the problem. The actual one I am trying to solve will be the general case, so e.g. type instance XEOverLit (GhcPass 'Parsed ) = RdrName type instance XEOverLit (GhcPass 'Renamed) = Name type instance XEOverLit (GhcPass 'Typechecked) = Id or more likely, modelling the existing PostTc and PostRn usages. And I suppose looking into using them in a single definition might work Alan On 13 November 2017 at 14:55, Simon Peyton Jones <simo...@microsoft.com<mailto:simo...@microsoft.com>> wrote: Or do I misunderstand your advice? Well, you said Where specifying the type instance with a wild card keeps GHC happy (the XXOverLit case), but specifying for each of the three constructors for pass does not (the XEOverLit case) My question is: why not just use the wildcard, in that case? Do you want to re-state the problem you are trying to solve? Simon From: Alan & Kim Zimmerman [mailto:alan.z...@gmail.com<mailto:alan.z...@gmail.com>] Sent: 13 November 2017 12:49 To: Simon Peyton Jones <simo...@microsoft.com<mailto:simo...@microsoft.com>> Cc: ghc-devs@haskell.org<mailto:ghc-devs@haskell.org> Subject: Re: Trees that Grow and constraints So why not use one? Simon If I do instance (Data p) => Data (Experiment p) then GHC does not know that the type instances for type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder type instance XEOverLit (GhcPass
Re: Trees that Grow and constraints
Isn't the solution always if generic programming makes things complicated, avoid it! Here generic programming is where you define instances parametric on the phase index. Why not defining three instances of the type class, one per each phase? Yes, we get code duplication (which in this case is still not much as we use automatic deriving), but the compilation gets faster (which is the motivation), like [2]. [2] http://lpaste.net/360019 /Shayan On Mon, Nov 13, 2017 at 2:05 PM, Alan & Kim Zimmermanwrote: > Just to clarify, this example is a simplification, in practice we would be > applying different type for each type instance > > e.g. > > type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder > type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder > type instance XEOverLit (GhcPass 'Typechecked) = Type > > (modelling existing PostTc) > > Alan > > On 13 November 2017 at 11:23, Alan & Kim Zimmerman > wrote: > >> At the moment the Trees that Grow implementation in GHC master makes use >> of massive constraint types to provide Data instances for the hsSyn AST. >> >> I am trying to remove the need for this, and have hit a problem. >> >> The example I have reduced it to is here [1] >> >> The essence of the problem is >> >> --- >> data Experiment p >> = Experiment { >> e_ext :: (XEOverLit p), >> e_val :: Int } >> | XExperiment (XXOverLit p) >> deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) >> >> type family XEOverLit x >> type family XXOverLit x >> >> -- The following line works >> -- type instance XEOverLit (GhcPass _) = PlaceHolder >> >> -- The following 3 lines do noe >> type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder >> type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder >> type instance XEOverLit (GhcPass 'Typechecked) = PlaceHolder >> >> type instance XXOverLit (GhcPass _) = PlaceHolder >> --- >> >> Where specifying the type instance with a wild card keeps GHC happy (the >> XXOverLit case), but specifying for each of the three constructors for pass >> does not (the XEOverLit case) >> >> The exact error message is >> >> -- >> Experiment.hs:34:1: error: >> • Could not deduce (Data (XEOverLit (GhcPass p))) >> arising from a use of ‘k’ >> from the context: Data (GhcPass p) >> bound by the instance declaration at Experiment.hs:34:1-69 >> • In the first argument of ‘k’, namely ‘(z Experiment `k` a1)’ >> In the expression: ((z Experiment `k` a1) `k` a2) >> In an equation for ‘gfoldl’: >> gfoldl k z Experiment a1 a2 = ((z Experiment `k` a1) `k` a2) >> When typechecking the code for ‘gfoldl’ >> in a derived instance for ‘Data (Experiment (GhcPass p))’: >> To see the code I am typechecking, use -ddump-deriv >>| >> 34 | deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) >>| >> ^ >> -- >> >> Alan >> >> [1] http://lpaste.net/360017 >> >> >> > > ___ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs > > ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: Trees that Grow and constraints
Just to clarify, this example is a simplification, in practice we would be applying different type for each type instance e.g. type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder type instance XEOverLit (GhcPass 'Typechecked) = Type (modelling existing PostTc) Alan On 13 November 2017 at 11:23, Alan & Kim Zimmermanwrote: > At the moment the Trees that Grow implementation in GHC master makes use > of massive constraint types to provide Data instances for the hsSyn AST. > > I am trying to remove the need for this, and have hit a problem. > > The example I have reduced it to is here [1] > > The essence of the problem is > > --- > data Experiment p > = Experiment { > e_ext :: (XEOverLit p), > e_val :: Int } > | XExperiment (XXOverLit p) > deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) > > type family XEOverLit x > type family XXOverLit x > > -- The following line works > -- type instance XEOverLit (GhcPass _) = PlaceHolder > > -- The following 3 lines do noe > type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder > type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder > type instance XEOverLit (GhcPass 'Typechecked) = PlaceHolder > > type instance XXOverLit (GhcPass _) = PlaceHolder > --- > > Where specifying the type instance with a wild card keeps GHC happy (the > XXOverLit case), but specifying for each of the three constructors for pass > does not (the XEOverLit case) > > The exact error message is > > -- > Experiment.hs:34:1: error: > • Could not deduce (Data (XEOverLit (GhcPass p))) > arising from a use of ‘k’ > from the context: Data (GhcPass p) > bound by the instance declaration at Experiment.hs:34:1-69 > • In the first argument of ‘k’, namely ‘(z Experiment `k` a1)’ > In the expression: ((z Experiment `k` a1) `k` a2) > In an equation for ‘gfoldl’: > gfoldl k z Experiment a1 a2 = ((z Experiment `k` a1) `k` a2) > When typechecking the code for ‘gfoldl’ > in a derived instance for ‘Data (Experiment (GhcPass p))’: > To see the code I am typechecking, use -ddump-deriv >| > 34 | deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) >| ^ > -- > > Alan > > [1] http://lpaste.net/360017 > > > ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: Trees that Grow and constraints
> So why not use one? > > > > Simon > > If I do instance (Data p) => Data (Experiment p) then GHC does not know that the type instances for type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder type instance XEOverLit (GhcPass 'Typechecked) = PlaceHolder apply. Or do I misunderstand your advice? Alan ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
RE: Trees that Grow and constraints
Where specifying the type instance with a wild card keeps GHC happy (the XXOverLit case), but specifying for each of the three constructors for pass does not (the XEOverLit case) Well, of course! The derived data instance looks something like instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) where gfoldl = ….Needs (Data (XEOverLit (GhcPass p)))… How can GHC solve the wanted constraint Data (XEOverlit (GhcPass p)) With three equations, it can’t. With one, it can. So why not use one? Simon From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Alan & Kim Zimmerman Sent: 13 November 2017 09:24 To: ghc-devs@haskell.org Subject: Trees that Grow and constraints At the moment the Trees that Grow implementation in GHC master makes use of massive constraint types to provide Data instances for the hsSyn AST. I am trying to remove the need for this, and have hit a problem. The example I have reduced it to is here [1] The essence of the problem is --- data Experiment p = Experiment { e_ext :: (XEOverLit p), e_val :: Int } | XExperiment (XXOverLit p) deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) type family XEOverLit x type family XXOverLit x -- The following line works -- type instance XEOverLit (GhcPass _) = PlaceHolder -- The following 3 lines do noe type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder type instance XEOverLit (GhcPass 'Typechecked) = PlaceHolder type instance XXOverLit (GhcPass _) = PlaceHolder --- Where specifying the type instance with a wild card keeps GHC happy (the XXOverLit case), but specifying for each of the three constructors for pass does not (the XEOverLit case) The exact error message is -- Experiment.hs:34:1: error: • Could not deduce (Data (XEOverLit (GhcPass p))) arising from a use of ‘k’ from the context: Data (GhcPass p) bound by the instance declaration at Experiment.hs:34:1-69 • In the first argument of ‘k’, namely ‘(z Experiment `k` a1)’ In the expression: ((z Experiment `k` a1) `k` a2) In an equation for ‘gfoldl’: gfoldl k z Experiment a1 a2 = ((z Experiment `k` a1) `k` a2) When typechecking the code for ‘gfoldl’ in a derived instance for ‘Data (Experiment (GhcPass p))’: To see the code I am typechecking, use -ddump-deriv | 34 | deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) | ^ -- Alan [1] http://lpaste.net/360017<https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Flpaste.net%2F360017=02%7C01%7Csimonpj%40microsoft.com%7C805caf6c0aac49f030ee08d52a785574%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636461618682611590=VxK0zeEmVsEahWRYMJ6xAG2gZviqGCd%2FHS4DrRXC0dM%3D=0> ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: Trees that Grow and constraints
And it seems that -- data Experiment p = Experiment { e_ext :: (XEOverLit p), e_val :: Int } | XExperiment (XXOverLit p) deriving instance (Data GhcPs) => Data (Experiment GhcPs) deriving instance (Data GhcRn) => Data (Experiment GhcRn) deriving instance (Data GhcTc) => Data (Experiment GhcTc) works, but only for GHC 8.2.1, not GHC 8.0.2 Alan On 13 November 2017 at 11:23, Alan & Kim Zimmermanwrote: > At the moment the Trees that Grow implementation in GHC master makes use > of massive constraint types to provide Data instances for the hsSyn AST. > > I am trying to remove the need for this, and have hit a problem. > > The example I have reduced it to is here [1] > > The essence of the problem is > > --- > data Experiment p > = Experiment { > e_ext :: (XEOverLit p), > e_val :: Int } > | XExperiment (XXOverLit p) > deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) > > type family XEOverLit x > type family XXOverLit x > > -- The following line works > -- type instance XEOverLit (GhcPass _) = PlaceHolder > > -- The following 3 lines do noe > type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder > type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder > type instance XEOverLit (GhcPass 'Typechecked) = PlaceHolder > > type instance XXOverLit (GhcPass _) = PlaceHolder > --- > > Where specifying the type instance with a wild card keeps GHC happy (the > XXOverLit case), but specifying for each of the three constructors for pass > does not (the XEOverLit case) > > The exact error message is > > -- > Experiment.hs:34:1: error: > • Could not deduce (Data (XEOverLit (GhcPass p))) > arising from a use of ‘k’ > from the context: Data (GhcPass p) > bound by the instance declaration at Experiment.hs:34:1-69 > • In the first argument of ‘k’, namely ‘(z Experiment `k` a1)’ > In the expression: ((z Experiment `k` a1) `k` a2) > In an equation for ‘gfoldl’: > gfoldl k z Experiment a1 a2 = ((z Experiment `k` a1) `k` a2) > When typechecking the code for ‘gfoldl’ > in a derived instance for ‘Data (Experiment (GhcPass p))’: > To see the code I am typechecking, use -ddump-deriv >| > 34 | deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) >| ^ > -- > > Alan > > [1] http://lpaste.net/360017 > > > ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Trees that Grow and constraints
At the moment the Trees that Grow implementation in GHC master makes use of massive constraint types to provide Data instances for the hsSyn AST. I am trying to remove the need for this, and have hit a problem. The example I have reduced it to is here [1] The essence of the problem is --- data Experiment p = Experiment { e_ext :: (XEOverLit p), e_val :: Int } | XExperiment (XXOverLit p) deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) type family XEOverLit x type family XXOverLit x -- The following line works -- type instance XEOverLit (GhcPass _) = PlaceHolder -- The following 3 lines do noe type instance XEOverLit (GhcPass 'Parsed ) = PlaceHolder type instance XEOverLit (GhcPass 'Renamed) = PlaceHolder type instance XEOverLit (GhcPass 'Typechecked) = PlaceHolder type instance XXOverLit (GhcPass _) = PlaceHolder --- Where specifying the type instance with a wild card keeps GHC happy (the XXOverLit case), but specifying for each of the three constructors for pass does not (the XEOverLit case) The exact error message is -- Experiment.hs:34:1: error: • Could not deduce (Data (XEOverLit (GhcPass p))) arising from a use of ‘k’ from the context: Data (GhcPass p) bound by the instance declaration at Experiment.hs:34:1-69 • In the first argument of ‘k’, namely ‘(z Experiment `k` a1)’ In the expression: ((z Experiment `k` a1) `k` a2) In an equation for ‘gfoldl’: gfoldl k z Experiment a1 a2 = ((z Experiment `k` a1) `k` a2) When typechecking the code for ‘gfoldl’ in a derived instance for ‘Data (Experiment (GhcPass p))’: To see the code I am typechecking, use -ddump-deriv | 34 | deriving instance (Data (GhcPass p)) => Data (Experiment (GhcPass p)) | ^ -- Alan [1] http://lpaste.net/360017 ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs