15

I was looking for the definition of seq and came across this weirdness. Why do all these functions have the same/similar definitions?

seq :: a -> b -> b
seq = let x = x in x

inline :: a -> a
inline = let x = x in x    

lazy :: a -> a
lazy = let x = x in x

There are many more with this definition in the source code. What's going on?

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
TheIronKnuckle
  • 7,224
  • 4
  • 33
  • 56

2 Answers2

21

What's going on is that these functions cannot be implemented in Haskell, but they should appear in the docs. Since haddock needs a syntactically correct (and well-typed) definition for each signature, the source must contain dummy definitions. Further, at the point where they are defined (in the ghc-prim package), error (and hence undefined) are not yet available, so the more obvious seq = error "Not implementable in Haskell" can't be used, thus the circular definition.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • 1
    Is there a reason `error` *can't* be defined earlier than `seq` and friends? – Dan Burton Dec 28 '11 at 21:11
  • 3
    `error` is defined as `throw (ErrorCall message)`, so for that you need the `Exception` mechanism and `Typeable`. It could be defined outside the`Exception` framework, directly using the `raise#` primitive, as far as I know, but it's nicer to have it fit in with the other `Exception`s. So to keep `ghc-prim` small, that only provides `raise#`, the more elaborate stuff goes into `base`. In short, it _could_ be defined earlier, but it's just not as nice, and there's no good reason to do it, the `GHC.Prim` source would be an unused dummy anyway. – Daniel Fischer Dec 28 '11 at 22:19
9

These definitions are a ruse: they're provided primitively by the GHC runtime. It turns out that the infinite loop let x = x in x can be given any type, so it's as good a ruse definition as any.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380