Void is surprisingly useful.
Void is surprisingly useful.
Posted Sep 9, 2026 9:56 UTC (Wed) by dcoutts (subscriber, #5387)Parent article: Stabilizing Rust's never type
Haskell has had a Void type in the standard library for over 10 years and it is surprisingly useful.
I guess Haskell borrowed the name void from C/C++.
In Haskell we represent it as a data type with no constructors, which is similar to Rust's empty enumeration.
data Void
-- | Since 'Void' values logically don't exist, this witnesses the
-- logical reasoning tool of \"ex falso quodlibet\".
--
absurd :: Void -> a
absurd a = case a of {}
Note the cute empty pattern match of {}, showing to the compiler that there are no cases. This empty pattern match trick is also useful in other contexts to show that certain cases are impossible (and thus don't need to be handled).
There isn't special compiler support for Void and it is not inserted as a last resort. In Haskell, functions that (very obviously) loop can be inferred to have a polymorphic result type, for example:
foo n = foo (n+1)
This will be inferred to have type
foo :: forall a b. Num a => a -> b
There's no special case in the language or type system here, this is just the most general type and thus the inferred type.
Notice the result is a universally quantified type: for any b. This can be instantiated at a call site at any type. The article describes this as coercion, but in a type system with polymorphism it's better understood as instantiating a polymorphic type variable for another (possibly concrete) type.
