New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mutually recursive expression types? #69
Comments
@ollef suggested that I generalise the types a little, perhaps modifying Consider the following condensed form of the types, which should be sufficient to demonstrate all the features of the actual problem. data Tm a = TmP a | TmI (Tm a) (Co a) | TmS (Scope' Tm a) (Scope' Co a)
data Co a = CoP a | CoI (Co a) (Tm a) | CoS (Scope' Co a) (Scope' Tm a) I managed to generalise it to the following, per the data Tm co a = TmP a | TmI (Tm co a) (co a) (Tm (Scope' (Tm co)) a) (Tm (Scope' co) a)
data Co tm a = CoP a | CoI (Co tm a) (tm a) (Co (Scope' (Co tm)) a) (Co (Scope' tm) a) and then take a sort of fixed-point for each: newtype Tm a = MkTm (TmF Co a)
newtype Co a = MkCo (CoF Tm a) but I don't know where to go from here. I don't think these fixed-points have |
I think what you have got here is strictly more general that what data Tm a b
= TmVar a | TmConv (Tm a) (Co b)
| TmPi (Tm a) (Scope () Tm a) | TmCoAbs (Tm a) (Scope () Co b) | ...
data Co a b = CoVar b | CoRefl (Tm a) | CoSym (Co b) | CoPiFst (Scope () Co b) ... then I think you have something that is kind of "bimonadic" in the sense that you have operations Tm a b -> (a -> Tm a' b') -> (b -> Co a' b')
Co a b -> (a -> Tm a' b') -> (b -> Co a' b') Then I think you can generalise the |
I did try something along similar lines (again, the idea was Olle's, who also came up with signatures similar to what you're describing):
I wrote Bifunctor etc instances but never got as far as what you (both) are suggesting. Something I just realised: I'm also missing another subtlety, which is that there are two types of binders in this language. In the attached images, Does this mean I should have two variants on |
Interesting. Yes, you might need two scopes, one which scopes over variables in the first type parameter and one which scopes over variables in the second. |
I tried to use |
You might want to look at something like how we handle this sort of thing in Ermine: That said, if I had it to do over again, I'd probably join the term and type level into one ADT and used one type of variable binding. Alternately, this is actually a good point where |
@ekmett thanks for the reference. I believe the so @tomjaguarpaw was right Indeed, we have http://lpaste.net/1398906578140135424 Edit: I've since corrected the indices in |
I think we can close this now, since I've more or less settled on an extra-Bound solution to my problem. |
I'm thinking about implementing the System DC language (from this paper, essentially "dependent GHC Core", to save you a click) using Bound.
The problem is that it has mutually recursive types for terms and coercions, like so:
so I don't think Monad instances are happening for either.
Some points:
Co
nodes appear in theTm
type, and vice versa, as notedScope b Co a
appears in both typesScope b Tm a
only appears in the first (as far as I can tell)How would I modify these types to support something akin to @gelisam's "sideways" imperative example?
The semantics I want are captured by the simple-minded types I wrote above; unlike in the
Imperative
example, I have no need for bound variables being unavailable in certain parts of the ASTs or anything of the sort.Edit: also see this comment below, it appears I need two kinds of binders
The text was updated successfully, but these errors were encountered: