Opened 2 years ago

Last modified 4 weeks ago

#11409 patch feature request

Cannot instantiate literals using TypeApplications

Reported by: Feuerbach Owned by:
Priority: normal Milestone: 8.6.1
Component: Compiler Version: 8.0.1-rc1
Keywords: TypeApplications Cc: adamgundry, int-index, dfeuer
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: #11352 Differential Rev(s): Phab:D4626
Wiki Page:

Description (last modified by Iceland_jack)

Relevant reddit post.


GHCi, version 8.0.1.20160110: http://www.haskell.org/ghc/  :? for help
Prelude> :set -XTypeApplications -fprint-explicit-foralls 
Prelude> :t 42
42 :: forall {a}. Num a => a
Prelude> 42 @Int

<interactive>:3:1: error:
    • Cannot not apply expression of type ‘a0’
      to a visible type argument ‘Int’
    • In the expression: 42 @Int
      In an equation for ‘it’: it = 42 @Int

(Also, "cannot not" looks like a typo.)

Change History (29)

comment:1 Changed 2 years ago by monoidal

This is discussed in the type application paper: https://www.seas.upenn.edu/~sweirich/papers/type-app-extended.pdf, B.4. Overloaded numbers.

comment:2 Changed 2 years ago by rwbarton

Also in ticket:5296#comment:17 and following comments.

comment:3 Changed 2 years ago by simonpj

Keywords: TypeApplications added
Owner: set to goldfire

It'd also be possible to define

integerLit :: Integer -> forall a. Num a => a
integerLit n = fromInteger n

arrange that 3 elaborates to integerLit 3 :: forall a. Num a => a`, and now that will work as expected.

This is so simple to do that it might be worth doing, just to avoid documenting the infelicity. After all, Haskell advertises that 3 :: forall a. Num a => a, so it's annoying if it doesn't behave like that.

comment:4 Changed 2 years ago by adamgundry

Cc: adamgundry added

See also #11352, which is about the same issue for the newfangled overloaded labels (and I guess overloaded string and rational literals should be treated similarly). I experimented with something like Simon's suggestion for overloaded labels, and found that error messages got worse, because it was no longer possible to give a CtOrigin that mentioned the overloaded label as the source. But perhaps there's a way round that?

Alternatively, I suppose we could add a special rule for typechecking a literal applied to a type.

comment:5 in reply to:  4 Changed 2 years ago by simonpj

Replying to adamgundry:

See also #11352, which is about the same issue for the newfangled overloaded labels (and I guess overloaded string and rational literals should be treated similarly).

OK, so that makes it more worth thinking about.

I experimented with something like Simon's suggestion for overloaded labels, and found that error messages got worse, because it was no longer possible to give a CtOrigin that mentioned the overloaded label as the source.

I don't understand why.

  • We continue to have a case in the type checker for integer literals, as now.
  • It elaborates the literal to integerLit 3 with type forall a. Num a => a

When we instantiate that type (which is delayed in the new TypeApplication world) we need a suitable CtOrigin. We get that using exprCtOrigin (see TcExpr.tcApp). It can produce a suitable origin for an integer literal, string -- or field label.

So it seems ok to me. Worth a try?

comment:6 Changed 2 years ago by adamgundry

I think you're right: my problems before arose because I was replacing the overloaded label with the function application in the typechecker, rather than preserving it until the desugarer. Hence exprCtOrigin saw the wrong thing.

On another topic, what about RebindableSyntax? At the moment we have (according to the manual):

An integer literal 368 means "fromInteger (368::Integer)", rather than "Prelude.fromInteger (368::Integer)".

comment:7 Changed 2 years ago by goldfire

I want to note that the Haskell Report says that 3 desugars to fromInteger THREE. Perhaps we can indeed hack around this by using integerLit. But then turning on RebindableSyntax would necessitate using fromInteger, which (due to its membership in the Num class), must have type forall a. Num a => Integer -> a, where the forall a just comes too early. This would mean that 3 @Int would work with -XNoRebindableSyntax but then fail with -XRebindableSyntax (when importing Prelude). It would all be rather unexpected. Worse than the status quo? I don't know.

comment:8 Changed 2 years ago by simonpj

I don't think it'd be too bad if GHC's implementation desugared 3 to integerLit THREE always. For Haskell 98 or 2010, the behaviour would be indistinguishable from the report. But it'd work with TypeApplications too which is a real advantage.

comment:9 Changed 2 years ago by goldfire

What about with RebindableSyntax? Changing that behavior would likely break quite a bit of code.

comment:10 Changed 2 years ago by simonpj

Yurgh. Maybe with RebindableSyntax we stick with fromInteger. Or maybe it's a breaking change.

Maybe we should do nothing until someone really says it's important to them.

comment:11 Changed 2 years ago by Richard Eisenberg <eir@…>

In 80b4c71c/ghc:

Fix typo in error message (#11409)

comment:12 Changed 2 years ago by goldfire

Do please merge the typo fix above. Thanks!

comment:13 Changed 2 years ago by bgamari

Milestone: 8.0.1
Resolution: fixed
Status: newclosed

Cherry-picked to ghc-8.0 as b7af30f79f7e3be105cdd17ee3369a5e483f7f3f.

comment:14 Changed 2 years ago by goldfire

Owner: goldfire deleted
Resolution: fixed
Status: closednew

Thanks for merging the typo fix. But that's nowhere near the nub of this ticket. We might well decide to do nothing, but I'm not convinced we've converged on that solution yet.

comment:15 in reply to:  14 Changed 2 years ago by thoughtpolice

Milestone: 8.0.18.2.1

Replying to goldfire:

Thanks for merging the typo fix. But that's nowhere near the nub of this ticket. We might well decide to do nothing, but I'm not convinced we've converged on that solution yet.

Agreed - in the mean time, let's put this to 8.2.1 since we're probably not going to introduce any large changes for 8.x.

comment:16 Changed 17 months ago by rwbarton

Type: bugfeature request

comment:17 Changed 16 months ago by bgamari

Milestone: 8.2.18.4.1

This won't be happening for 8.2.

comment:18 Changed 14 months ago by Iceland_jack

Description: modified (diff)

comment:19 Changed 14 months ago by int-index

I think the correct way forward here is changing how -XTypeApplications works with partially applied functions. If I can write fromInteger @t n, shouldn't fromInteger n @t behave the same?

comment:20 Changed 14 months ago by int-index

Cc: int-index added

comment:21 Changed 14 months ago by dfeuer

Cc: dfeuer added

comment:22 Changed 14 months ago by rwbarton

f n @t can already be valid and different from f @t n though.

comment:23 Changed 14 months ago by goldfire

The question always is: what type variable is being instantiated? Perhaps f has the type forall a. a -> forall b. b -> (a, b). Then f @t n will be different from f t @n. And, as Stephanie and I describe in our paper, there doesn't seem to be a way to add in extra flexibility.

comment:24 Changed 11 months ago by Iceland_jack

Mentioned in reddit comment

I keep being surprised/disappointed that I can't do 5 @Int and have to do (5 :: Int) instead.

comment:25 Changed 11 months ago by adamgundry

Rather than defining integerLit, perhaps we should just treat a type application to an overloaded literal specially, and say that 5 @Int desugars to fromInteger @Int 5? This would work with RebindableSyntax just fine.

comment:26 in reply to:  25 Changed 11 months ago by Iceland_jack

That sounds good Adam

comment:27 Changed 4 months ago by bgamari

Milestone: 8.4.18.6.1

This ticket won't be resolved in 8.4; remilestoning for 8.6. Do holler if you are affected by this or would otherwise like to work on it.

comment:28 Changed 4 weeks ago by isovector

Differential Rev(s): Phab:D4626
Status: newpatch

comment:29 Changed 4 weeks ago by simonpj

Sandy Maguire (isovector) has authored

Next steps: community feedback on the above proposal

Last edited 4 weeks ago by simonpj (previous) (diff)
Note: See TracTickets for help on using tickets.