Could someone explain why there is 27
different Bool->Bool
values, from which 11
can be definied in Haskell?

- 463
- 3
- 10
-
1What do you mean by "`Bool->Bool` values"? Do you mean functions with the type signature `Bool -> Bool`? – mhwombat Sep 10 '13 at 10:47
1 Answers
There are three values of type Bool
: True
, False
and bottom (expressions for which the evaluation doesn't finish or expressions for which the evaluation turns into errors).
Then, there are an exponential number of functions from A
to B
. More exactly |B| ^ |A|
.
Thus, there are 3^3 = 27
functions of type Bool -> Bool
.
Now, for the second part of the question: function starting from bottom can be only 2: the one constantly returning True
and the one constantly returning False
. Then you have to add the number of functions from {True, False}
to {True, False, bottom}
which is 3^2
. So, in total you'll have 9+2=11
functions.
Edit: Here are the 11 possible functions:
B
is bottom, T
is True
, F
is False
. The last row represents the const True
and the const False
functions while the first three rows represent functions testing the value of the argument. That is why the first three rows map B
to B
: testing the value of bottom cannot result in anything else but bottom.
I hope it is clearer now.

- 20,967
- 7
- 57
- 109
-
16Just to elaborate on the second part: the reason you can only define a subset is that you can't test the input of the function for being bottom. Think of the case when the bottom is an infinite computation: the only reliable way to observe that it's an infinite computation is to observe it (halting problem, etc), which will never terminate. So you can only do three things with the input: test for True, test for False, or ignore it. – Neil Brown Sep 10 '13 at 11:21
-
I can't see why you can define `True -> bottom`, but not `bottom -> bottom` (which you don't count). – Sassa NF Sep 10 '13 at 12:19
-
2`bottom -> bottom` cannot exist because you cannot know if the argument is `bottom`. – Mihai Maruseac Sep 10 '13 at 12:20
-
@SassaNF: I've added a diagram with all 11 functions and an explanation which also contains Neil's comment. – Mihai Maruseac Sep 10 '13 at 12:50
-
3I agree with the diagram, but not your original explanation. Once you want to map True -> something, you can only map bottom to bottom (cannot map bottom to something else). This limits the choice of where bottom can be mapped. (Neil mentioned this) Plus there are constant functions that map everything to the same value. But you do not make this connection, instead you declare only two possible mappings from bottom. As is clear from the diagrams, there are three possible mappings from bottom, but one overlaps with the functions counted in 3^2. – Sassa NF Sep 10 '13 at 13:32
-
I was scratching my head on this but @SassaNF's comment that it's not that `const undefined` doesn't count, but that it only counts once made everything clear for me. – Paul Visschers Sep 10 '13 at 14:53
-
8There's actually 28 inhabitants of the type, since functions can be bottom as well. However, `const undefined` can't be distinguished from `undefined` except in the presence of `seq`. This is all why I prefer fast and loose reasoning.. – Carl Sep 10 '13 at 15:03
-
@Carl: Isn't `const undefined True` different from `undefined True`? – Paul Visschers Sep 10 '13 at 15:24
-
@PaulVisschers What's the definition of "different"? They're not the same code, but how would you go about telling them apart? Even with `seq` and the exception tools available in IO, I can't see how to distinguish those exact expressions typed as `Bool`. – Carl Sep 10 '13 at 15:50
-
@Carl: Sorry I completely flaked on the meaning of `const`, for some reason I was thinking about `flip const` instead in which case they are clearly different. Nevermind my nonsense, you were correct. – Paul Visschers Sep 10 '13 at 15:56