Injective type families
Richard Eisenberg
eir at cis.upenn.edu
Thu Jul 10 15:47:30 UTC 2014
I'm not convinced I have very good taste where it comes to concrete syntax, but I will say that the `injective` keyword below is redundant -- it can be inferred from the presence of the `|`.
Also, by restriction (b), I imagine you also allow things like `Maybe a`, where `a` is a variable bound on the LHS. That doesn't seem to be included in a tight reading of your proposal.
Thanks for taking this on!
Richard
On Jul 10, 2014, at 10:37 AM, Jan Stolarek <jan.stolarek at p.lodz.pl> wrote:
> Hi all,
>
> I'd like to take a stab at implementing injective type families (#6018). My plan of attack looks
> like this:
>
> 1. Implement injective type families that are:
> a) injective in all arguments
> b) only admit RHS that is a concrete type or a type variable introduced by the LHS or a
> recursive call to self.
> 2. Lift restriction a) ie. allow type families injective only in some arguments
> 3. Lift restriction b) ie. allow injective type families to call other type families.
>
> I'm not sure if 3) really gets implemented as this seems more in lines of #4259, which I don't
> intend to approach.
>
> Now, let's discuss the most important of all matters - the syntax! :-) Note that syntax must:
> 1. allow to define injectivity only for some parameters
> 2. work for both open and closed type families
>
> Here's my proposal (based on Richard's idea to use functional-dependencies-like syntax):
>
> 1. Standard injective type family (all parameters uniquely determined by the RHS):
>
> injective type family F a b c | a b c
> type family instance F Int Char Bool = Bool
> type family instance F Char Bool Int = Int
> type family instance F Bool Int Char = Char
>
> 2. Type family injective only in some parameters (ie. only some parameters uniquely determined by
> the RHS):
>
> injective type family G a b c | a b
> type family instance G Int Char Bool = Bool
> type family instance G Int Char Int = Bool
> type family instance G Bool Int Int = Int
>
> Here knowing the RHS allows us to determine a and b, but not c.
>
> 3. Type families where knowing the RHS and some parameters on the LHS makes other parameters
> injective:
>
> Example 1: knowing the RHS and any single parameter uniquely determines other parameters
>
> injective type family H a b c | a -> b c, b -> a c, c -> a b
> type family instance H Int Char Double = Int
> type family instance H Bool Double Char = Int
>
> Example 2: knowing the RHS and either a or b allows to uniquely determine other parameters, but
> knowing the RHS and c gives us no information about a or b
>
> injective type family J a b c | a -> b c, b -> a c
> type family instance J Int Char Double = Int
> type family instance J Bool Double Double = Int
>
> For closed type families this notation would be identical: type family declaration would be
> followed by the "where" keyword.
>
> In comment 34 of #6018 Richard proposed a notation that uses a keyword "Result". This would allow
> for a more uniform notation. Notice that in my proposal some families use ->, while others don't.
> The idea is that on the right side of the arrow we write what we can infer from the things on the
> left of the arrow. If the only thing left of the arrow is the right hand side of the type family
> equation (the result) then the arrow can be elided. In other words these would be equivalent:
>
> injective type family F a b c | a b c
> injective type family F a b c | result -> a b c
>
> injective type family G a b c | a b
> injective type family G a b c | result -> a b
> (note: it is also true that "injective type family G a b c | result c -> a b")
>
> injective type family H a b c | a -> b c, b -> a c, c -> a b
> injective type family H a b c | result a -> b c, result b -> a c, result c -> a b
>
> injective type family J a b c | a -> b c, b -> a c
> injective type family J a b c | result a -> b c, result b -> a c
>
> I find the notation explicitly using "result" to be easier to understand, but it is also more
> verbose. I also suspect that it might be a bit easier to parse. Which of the notations do you
> find better? What do you think about using the "injective" keyword? Are there any alternative
> proposals?
>
> Janek
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://www.haskell.org/mailman/listinfo/ghc-devs
More information about the ghc-devs
mailing list