4

When a GHCi session loads a file with {-# LANGUAGE NoImplicitPrelude #-} directive, it will unload most of the Prelude definitions:

GHCi, version 8.10.6: https://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /path/to/.ghci
[1 of 1] Compiling Main             ( Main.hs, interpreted )
Ok, one module loaded.
<interactive>:1:1: error: Variable not in scope: main
> :i id
<interactive>:1:1: error: Not in scope: ‘id’

Some "fundamental" definitions stays imported, nevertheless:

> :i ->
type (->) :: * -> * -> *
data (->) a b
    -- Defined in ‘GHC.Prim’
infixr -1 ->
> :i []
type [] :: * -> *
data [] a = [] | a : [a]
    -- Defined in ‘GHC.Types’
> :i :
type [] :: * -> *
data [] a = ... | a : [a]
    -- Defined in ‘GHC.Types’
infixr 5 :
> 

What I want to know is: Is there more of such definitions available without importing Prelude? Is there a complete list of them, or a way to generate it?

A previous Google search for haskell no prelude (expectedly) did not give something useful. The No import of Prelude page in Haskell Wiki mentions that:

There are some such for which even -fno-implicit-prelude isn't enough; I think these are documented in the "bugs" section of the GHC manual.

I did not find (or missed) any relevent information there; I don't know where to look in the rest of GHC User's Guide, either.

  • 2
    You're referring to an edit made to a wiki page 15 years ago, which even at the time said "I *think* it's documented". Whether it was documented or not at the time, it's not at all surprising to me that this old wiki page is no longer accurate. That said, there's nothing wrong with the overall question; it would be nice to know what syntax is blessed enough that it can't be opted out of. – amalloy Feb 21 '23 at 11:19

2 Answers2

4

I don't know where to find documentation or implementation code confirming this explicitly, but here is what I would expect the answer to be, and I can't disprove it. The definitions that "survive" NoImplicitPrelude are those that a Haskell programmer could not define themselves, i.e. those that use special syntax that GHC has to know about. You've already highlighted the special syntax for lists, and : is included because it's not really a legal name for a user-defined identifier.

If you poke around, you will discover that tuples all exist as well. After that, you have to start getting philosophical about what you consider a "definition". Is it surprising that 0 still works? Or should that have been exiled because it uses Prelude.Num?

chi
  • 111,837
  • 3
  • 133
  • 218
amalloy
  • 89,153
  • 8
  • 140
  • 205
  • “Is it surprising that 0 still works?” – it _doesn't_ work if using `-XNoImplicitPrelude` together with `-XRebindableSyntax`. – leftaroundabout Feb 22 '23 at 10:02
2

There is also (~) which weirdly is not in scope if you use :i, but it does give you its kind (with GHC 9.4.4):

ghci> :i (~)

<interactive>:1:1: error: Not in scope: ‘~’
ghci> :k (~)
(~) :: k -> k -> Constraint
Noughtmare
  • 9,410
  • 1
  • 12
  • 38