Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#10548 closed feature request (fixed)

Support PartialTypeSignatures in Template Haskell

Reported by: spinda Owned by: thomasw
Priority: normal Milestone: 8.0.1
Component: Template Haskell Version: 7.10.1
Keywords: newcomer Cc: thomasw, adamgundry
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case: comment:17
Blocked By: Blocking:
Related Tickets: Differential Rev(s): Phab:D1048
Wiki Page:

Description

Currently Template Haskell cannot emit Types with wildcards as in PartialTypeSignatures.

A data constructor for wildcards (eg. WildcardT (Maybe Name)) could be added to Type, which would be converted to wildcards in GHC.

Change History (18)

comment:1 Changed 4 years ago by goldfire

Keywords: newcomer added

Adding new language features to TH is a fantastic way to start hacking on GHC. (Proof: it was my first contribution.)

comment:2 Changed 4 years ago by spinda

I believe an implementation would consist of:

(1) Add a WildcardT (Maybe Name) data constructor to the declaration of Language.Haskell.TH.Syntax.Type.

(2) Add a new branch to cvtTypeKind that translates this to either HsWildcardTy or HsNamedWildcardTy, depending on the Maybe Name value.

comment:3 Changed 4 years ago by goldfire

Without looking at the code myself, this sounds entirely reasonable to me.

comment:4 Changed 4 years ago by adamgundry

Cc: thomasw adamgundry added

I'd also like this (see #10094). I looked at it briefly and it didn't seem to be completely trivial, because the implementation traversed types to collect wildcards prior to renaming the type, and the presence of TH type splices means that it's hard to know up front whether wildcards will be present. But 058af6c90a0e8d122f2d1339b6b4fd0b5ec83d05 may have made it easier.

Perhaps thomasw can advise further?

comment:5 Changed 4 years ago by thomasw

Owner: set to thomasw

comment:6 Changed 4 years ago by thomasw

The changes to TH itself are straightforward. However Adam is right, the (named) wild cards must be known before renaming starts while TH type splices are run during renaming.

Besides a small bug I'm looking into, I see no problem with supporting anonymous wild cards in TH type splices. Named wild cards will require much more work and a refactoring of how splices and wild cards interact during renaming.

Does it make sense to only allow anonymous wild cards in TH type splices but not named wild cards?

Last edited 4 years ago by thomasw (previous) (diff)

comment:7 Changed 4 years ago by thomasw

I forgot to add that extra-constraints wild cards (_ => ...) have the same problem as named wild cards: they must be known before renaming.

If people are ok with only having anonymous type wild cards in TH type splices, then I'll post a diff on Phabricator.

comment:8 Changed 4 years ago by adamgundry

Thanks for looking at this! I can't speak for everyone, but for my use case I need only anonymous type wild cards, not named or extra-constraints wild cards. Please do post a diff. We can perhaps put off the extra work until anyone comes up with a reason for wanting the other cases...

comment:9 Changed 4 years ago by thomasw

Differential Rev(s): Phab:D1048

comment:10 Changed 4 years ago by spinda

Ideally I'd like to see all type features accessible from TH, but this fits my use case right now.

Thanks!

comment:11 Changed 4 years ago by thomasw

Actually, this limitation only applies to type splices. I had forgotten about declaration splices, which can also contain type signatures, until goldfire reminded me. My patch on Phabricator adds full support for partial type signatures in declaration splices in addition to support for anonymous wild cards in type splices.

comment:12 Changed 4 years ago by Ben Gamari <ben@…>

In 49373ffe/ghc:

Support wild cards in TH splices

- Declaration splices: partial type signatures are fully supported in TH
  declaration splices.

  For example, the wild cards in the example below will unify with `Eq
a`
  and `a -> a -> Bool`, as expected:

```
[d| foo :: _ => _
    foo x y = x == y |]
```

- Expression splices: anonymous and named wild cards are supported in
  expression signatures, but extra-constraints wild cards aren't. Just
  as is the case for regular expression signatures.

```
[e | Just True :: _a _ |]
```

- Typed expression splices: the same wildcards as in (untyped)
  expression splices are supported.

- Pattern splices: TH doesn't support type signatures in pattern
  splices, consequently, partial type signatures aren't supported
  either.

- Type splices: partial type signatures are only partially supported in
  type splices, specifically: only anonymous wild cards are allowed.

  So `[t| _ |]`, `[t| _ -> Maybe _ |]` will work, but `[t| _ => _ |]` or
  `[| _a |]` won't (without `-XNamedWildCards`, the latter will work as
  the named wild card is treated as a type variable).

  Normally, named wild cards are collected before renaming a (partial)
  type signature. However, TH type splices are run during renaming, i.e.
  after the initial traversal, leading to out of scope errors for named
  wild cards. We can't just extend the initial traversal to collect the
  named wild cards in TH type splices, as we'd need to expand them,
  which is supposed to happen only once, during renaming.

  Similarly, the extra-constraints wild card is handled right before
  renaming too, and is therefore also not supported in a TH type splice.
  Another reason not to support extra-constraints wild cards in TH type
  splices is that a single signature can contain many TH type splices,
  whereas it mustn't contain more than one extra-constraints wild card.
  Enforcing would this be hard the way things are currently organised.

  Anonymous wild cards pose no problem, because they start without names
  and are given names during renaming. These names are collected right
  after renaming. The names generated for anonymous wild cards in TH
  type splices will thus be collected as well.

  With a more invasive refactoring of the renaming, partial type
  signatures could be fully supported in TH type splices. As only
  anonymous wild cards have been requested so far, these small changes
  satisfying this request will do for now. Also don't forget that a TH
  declaration splices support all kinds of wild cards.

- Extra-constraints wild cards were silently ignored in expression and
  pattern signatures, appropriate error messages are now generated.

Test Plan: run new tests

Reviewers: austin, goldfire, adamgundry, bgamari

Reviewed By: goldfire, adamgundry, bgamari

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1048

GHC Trac Issues: #10094, #10548

comment:13 Changed 4 years ago by thomie

Milestone: 7.12.1
Resolution: fixed
Status: newclosed

comment:14 Changed 4 years ago by simonpj

Are there some feature tests for this?

Simon

comment:15 in reply to:  14 Changed 4 years ago by thomasw

Replying to simonpj:

Are there some feature tests for this?

Yes, I think I added tests for all splices, including the scenarios in which wild cards aren't supported.

comment:16 Changed 4 years ago by simonpj

Terrific. So can you add them to the "Test case" field of this ticket? Or if too many, list them in a comment, and in the "Test case" field say "see comment:23" of whatever?

comment:17 Changed 4 years ago by bgamari

Test Case: comment:17

D1048 included the following tests,

  • ExtraConstraintsWildcardInExpressionSignature
  • ExtraConstraintsWildcardInPatternSignature
  • ExtraConstraintsWildcardInPatternSplice
  • ExtraConstraintsWildcardInTypeSplice
  • ExtraConstraintsWildcardInTypeSplice2
  • ExtraConstraintsWildcardInTypeSpliceUsed
  • NamedWildcardInTypeSplice
  • WildcardInTypeBrackets

comment:18 Changed 4 years ago by thoughtpolice

Milestone: 7.12.18.0.1

Milestone renamed

Note: See TracTickets for help on using tickets.