[GHC] #6018: Injective type families
GHC
ghc-devs at haskell.org
Tue Oct 14 12:30:42 UTC 2014
#6018: Injective type families
-------------------------------------+-------------------------------------
Reporter: lunaris | Owner: jstolarek
Type: feature | Status: new
request | Milestone: 7.10.1
Priority: normal | Version: 7.4.1
Component: Compiler | Keywords: TypeFamilies,
Resolution: | Injective
Operating System: | Architecture: Unknown/Multiple
Unknown/Multiple | Difficulty: Unknown
Type of failure: | Blocked By:
None/Unknown | Related Tickets: #4259
Test Case: |
Blocking: |
Differential Revisions: Phab:D202 |
-------------------------------------+-------------------------------------
Comment (by goldfire):
Replying to [comment:84 jstolarek]:
> Richard, either I'm not getting the subtleties of your arguments or
you're misunderstanding what I meant to say on the wiki page. Or both :-)
>
> I now see the theoretical difference between "overlaps" and "subsumes"
but I don't yet see how that is important in my algorithm outline. I re-
read parts of the closed type families paper and now I'm not even sure
whether I meant "overlaps" or "unifies".
To be clear, I am considering the expressions "two types overlap" and "two
types unify" to be synonymous. Subsumption is a finer, directed relation
between types than overlap/unify.
> {{{#!hs
> type family E1 a = r | r -> a where ...
> }}}
Yes yes yes. You're right here. I was wrong. The wiki page is updated.
>
> Now `E2`:
>
> {{{#!hs
> type family E2 (a:: Bool) = r | r -> a where
> E2 False = True
> E2 True = False
> E2 a = False
> }}}
> I consider almost identical example on the wiki:
> {{{#!hs
> type family Bak a = r | r -> a where
> Bak Int = Char
> Bak Char = Int
> Bak a = a
> }}}
> The difference is the RHS of the last equation: a concrete type in your
example, a type variable in mine. Yet I believe that both examples are
intended to demonstrate the same problem - see discussion below that
example.
I think these cases are different. In yours, the RHS unification (`a`
unifies with `Char`) refines the LHS (`a |-> Char`) so that it is subsumed
by an earlier equation. This action does not happen in my example, and
different reasoning (noting that `False` and `True` are both impossible)
is required.
> I have a question about closed type families paper. Paragraph just after
Candidate Rule 2 (section 3.2, page 3) says: "As a notational convention,
apart(ρ, τ) considers the lists ρ and τ as tuples of types; the apartness
check does ''not'' go element-by-element.", where "not" is emphasized. Why
is this important? Seems like the choice of representing patterns and
types as tuples or lists is just an implementation detail.
Agreed that choosing a list vs. a tuple is irrelevant, but choosing
element-by-element vs. as-a-whole is quite important. For example `(a, a)`
is quite apart from `(Int, Bool)`, when considered as a whole, even though
`a` is neither apart from `Int` nor `Bool` looking at individual elements.
Does that clarify?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/6018#comment:85>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list