If you're representing error conditions as part of a mathematical type, you're definitely doing it wrong.
The correct way to do this is to have a type that explicitly deals with errors, and use this to wrap the mathematical type.
This type is usually called Maybe or Option. For example, in Rust, you can have a `Option<bool>`, which can have one of three values: `None` (which might represent an error), `Some(true)`, or `Some(false)`.
The important thing is that you're not making some weird, poorly thought out kludge type. You're composing two clean and simple types in an obvious way.
Logic circuits are frequently modeled with four states: 0, 1, X, and Z. X means unknown, or "don't care" in some contexts. Z usually means high impedance.
On most SQL servers you have three values for bool, TRUE, FALSE, and NULL. There is either nullable or non-nullable types of bool, but at some stage you'll need the nullable one so it is useful to have the triple implementation in the language (particularly for an entity framework implementation).
For example C# now supports this via their (bool?) type (i.e. nullable bool). However the default language construct is just a two value bool (bool).
The correct way to do this is to have a type that explicitly deals with errors, and use this to wrap the mathematical type.
This type is usually called Maybe or Option. For example, in Rust, you can have a `Option<bool>`, which can have one of three values: `None` (which might represent an error), `Some(true)`, or `Some(false)`.
The important thing is that you're not making some weird, poorly thought out kludge type. You're composing two clean and simple types in an obvious way.