New type of ($) operator in GHC 8.0 is problematic

Ben Gamari ben at
Sat Feb 13 12:41:48 UTC 2016

Ryan Scott < at> writes:

> Hi Chris,
> The change to ($)'s type is indeed intentional. The short answer is
> that ($)'s type prior to GHC 8.0 was lying a little bit. If you
> defined something like this:
>     unwrapInt :: Int -> Int#
>     unwrapInt (I# i) = i

Hello everyone,

While this thread continues to smolder, it seems that the arguments
relevant to the levity polymorphism change have been sussed out. Now
seems like a good time to review what we have all learned,

 * In 7.10 and earlier the type of ($) is a bit of a lie as it did not
   reflect the fact that the result type was open-kinded.

   ($) also has magic to allow impredicative uses, although this is
   orthogonal to the present levity discussion.
 * the type of ($) has changed to become more truthful in 8.0: we now
   capture lifted-ness in the type system with the notion of Levity.

 * there is widespread belief that the new type is too noisy and
   obfuscates the rather simple concept embodied by ($). This is
   especially concerning for those teaching and learning the language.

 * One approach to fix this would be to specialize ($) for lifted types
   and introduce a new levity polymorphic variant. This carries the
   potential to break existing users of ($), although it's unclear how
   much code this would affect in practice.

 * Another approach would be to preserve the current lie with
   pretty-printer behavior. This would be relatively easy to do and
   would allow us to avoid breaking existing users of ($). This,
   however, comes at the expense of some potential confusion when
   polymorphism is needed.

 * There are further questions regarding the appropriate kinds
   of (->) and (.) [1]

 * Incidentally, there is a GHC or Haddock bug [2] which causes kind
   signatures to be unnecessarily shown in documentation for some types,
   exposing levities to the user.

The current plan to address this situation is as follows,

 * Introduce [3] a flag, -fshow-runtime-rep, which when disabled will
   cause the pretty-printer to instantiate levity-polymorphic types as
   lifted (e.g. resulting in *). This flag will be off by default,
   meaning that users will in most cases see the usual lifted types
   unless they explicitly request otherwise.

 * Fix the GHC/Haddock bug, restoring elision of unnecessary kind
   signatures in documentation.

 * In the future we should seriously consider introducing an alternate
   Prelude for beginners
As far as I can tell from the discussion, this was an acceptable
solution to all involved. If there are any remaining objections or
concerns let's discuss them in another thread.

Thanks to everyone who contributed to this effort.


- Ben

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 472 bytes
Desc: not available
URL: <>

More information about the ghc-devs mailing list