I\'m reading Learn You a Haskell, and in the monad chapters, it seems to me that () is being treated as a sort of \"null\" for every type. When I check
The confusion comes from other programming languages: "void" means in most imperative languages that there is no structure in memory storing a value. It seems inconsistent because "boolean" has 2 values instead of 2 bits, while "void" has no bits instead of no values, but there it is about what a function returns in a practical sense. To be exact: its single value consumes no bit of storage.
Let's ignore the value bottom (written _|_) for a moment...
() is called Unit, written like a null-tuple. It has only one value. And it is not called
Void, because Void has not even any value, thus could not be returned by any function.
Observe this: Bool has 2 values (True and False), () has one value (()), and Void has no value (it doesn't exist). They are like sets with two/one/no elements. The least memory they need to store their value is 1 bit / no bit / impossible, respectively. Which means that a function that returns a () may return with a result value (the obvious one) that may be useless to you. Void on the other hand would imply that that function will never return and never give you any result, because there would not exist any result.
If you want to give "that value" a name, that a function returns which never returns (yes, this sounds like crazytalk), then call it bottom ("_|_", written like a reversed T). It could represent an exception or infinity loop or deadlock or "just wait longer". (Some functions will only then return bottom, iff one of their parameters is bottom.)
When you create the cartesian product / a tuple of these types, you will observe the same behaviour:
(Bool,Bool,Bool,(),()) has 2·2·2·1·1=6 differnt values. (Bool,Bool,Bool,(),Void) is like the set {t,f}×{t,f}×{t,f}×{u}×{} which has 2·2·2·1·0=0 elements, unless you count _|_ as a value.