($) can have a more general type
The documentation (in section 9.12.1 for GHC 8; I don't know what section it is in 8.2) suggests a hypothetical type for ($)
:
bad :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
(a :: TYPE r1) (b :: TYPE r2).
(a -> b) -> a -> b
bad f x = f x
It explains, correctly, that this definition will not work because x
has a representation-polymorphic type. However, this doesn't actually explain why ($)
doesn't have that type! Indeed, both GHC 8 and 8.2 accept the following:
good :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep)
(a :: TYPE r1) (b :: TYPE r2).
(a -> b) -> a -> b
good f = f
This has very slightly different semantics, but anyone relying on the difference is already doing something they shouldn't. It may or may not be possible to retain the current semantics with some care and magic, if we so desire.
I didn't really know how to characterize this ticket properly. It could be considered a documentation bug or a compiler feature request.
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (Type checker) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |