This would be a valid mathematical function with no fixpoint, but you cannot define it in Haskell. Here are two perspectives on why:
- You cannot pattern-match on ⊥, nor compare to it. Although it’s useful to think of ⊥ as a value, remember that really it just represents a computation that doesn’t terminate. Asking the computer to determine whether a value is ⊥ or not is, quite literally, asking to solve the halting problem!
- Equivalently, the problem is that your function is not monotone in the definedness order. If f(⊥) = 1, then anything more defined than ⊥ — and that is everything at all — must map to something more defined than 1. (Since 1 is completely defined, that means they must map to 1 exactly. So if f(⊥) = 1, then f must be a constant function.)
Another way to look at being monotone in the definedness order is to think of ⊥ as meaning “I don’t know yet!”. If you later learn more about the input, you can still learn more about the output; but you cannot contradict what you already supposedly knew. That would be logically inconsistent. Saying f(⊥) = 1 is saying that if you don’t yet know anything at all about the input, then you still already know that the output is 1. Fine, but then you cannot turn around and say that f(1) = 2. By contrast, it’s fine if, say, g(⊥) = 1 : ⊥, but g(1) = 1 : . That just says that without knowing anything about the input, you already know the output is a list that starts with 1; but if you know the input is 1, then you learn something more: the 1 is the only element of the output list. It doesn’t contradict what you already knew. That’s what it means for the function to be monotone. In Haskell, you can only define monotone functions.