There is no way to construct a "real" value of a no-constructor type (where by "real" I mean a terminating computation; Haskell has undefined :: a
, error :: String -> a
and the possibility of writing nonterminating programs like mwahaha = mwahaha
, which to be simplistic I'll call "fake" values).
One example of how this can be useful is versions 0.5 and later of the conduit library. The basic type in the library is Pipe l i o u m r
; with different parameters for these types, a Pipe
can serve either as a source (which produces output without consuming any input), a sink (consumes input without producing any output), or a conduit (consumes input and produces output). The i
and o
type parameters to Pipe
are the types of its input and output, respectively.
So one of the ways the conduit library enforces the notion that sources consume no input and sinks produce no output by using the Void
type from Data.Void
as the input type for sources and output type for sinks. Again, there is no terminating way to construct a value of such a type, so a program that attempts to consume output from a sink will not terminate (which as a reminder, in Haskell this can mean "raise an error" and not necessarily "loop forever").