7.12. Special built-in functions
Prev | Chapter 7. GHC Language Features | Next

## 7.12. Special built-in functions

GHC has a few built-in funcions with special behaviour, described in this section. All are exported by `GHC.Exts`.

### 7.12.1. The `seq` function

The function `seq` is as described in the Haskell98 Report.

      seq :: a -> b -> b

It evaluates its first argument to head normal form, and then returns its second argument as the result. The reason that it is documented here is that, despite `seq`'s polymorphism, its second argument can have an unboxed type, or can be an unboxed tuple; for example `(seq x 4#)` or `(seq x (# p,q #))`. This requires `b` to be instantiated to an unboxed type, which is not usually allowed.

### 7.12.2. The `inline` function

The `inline` function is somewhat experimental.

      inline :: a -> a

The call `(inline f)` arranges that `f` is inlined, regardless of its size. More precisely, the call `(inline f)` rewrites to the right-hand side of `f`'s definition. This allows the programmer to control inlining from a particular call site rather than the definition site of the function (c.f. `INLINE` pragmas Section 7.10.3, “INLINE and NOINLINE pragmas”).

This inlining occurs regardless of the argument to the call or the size of `f`'s definition; it is unconditional. The main caveat is that `f`'s definition must be visible to the compiler. That is, `f` must be let-bound in the current scope. If no inlining takes place, the `inline` function expands to the identity function in Phase zero; so its use imposes no overhead.

If the function is defined in another module, GHC only exposes its inlining in the interface file if the function is sufficiently small that it might be inlined by the automatic mechanism. There is currently no way to tell GHC to expose arbitrarily-large functions in the interface file. (This shortcoming is something that could be fixed, with some kind of pragma.)

### 7.12.3. The `lazy` function

The `lazy` function restrains strictness analysis a little:

      lazy :: a -> a

The call `(lazy e)` means the same as `e`, but `lazy` has a magical property so far as strictness analysis is concerned: it is lazy in its first argument, even though its semantics is strict. After strictness analysis has run, calls to `lazy` are inlined to be the identity function.

This behaviour is occasionally useful when controlling evaluation order. Notably, `lazy` is used in the library definition of `Control.Parallel.par`:

      par :: a -> b -> b
      par x y = case (par# x) of { _ -> lazy y }

If `lazy` were not lazy, `par` would look strict in `y` which would defeat the whole purpose of `par`.

Like `seq`, the argument of `lazy` can have an unboxed type.

### 7.12.4. The `unsafeCoerce#` function

The function `unsafeCoerce#` allows you to side-step the typechecker entirely. It has type

      unsafeCoerce# :: a -> b

That is, it allows you to coerce any type into any other type. If you use this function, you had better get it right, otherwise segmentation faults await. It is generally used when you want to write a program that you know is well-typed, but where Haskell's type system is not expressive enough to prove that it is well typed.

The argument to `unsafeCoerce#` can have unboxed types, although extremely bad things will happen if you coerce a boxed type to an unboxed type.

Prev | Up | Next
7.11. Rewrite rules | Home | 7.13. Generic classes