I've searched around the Internet, and I can't find any explanations of CHI which don't rapidly degenerate into a lecture on logic theory which is drastically over my head. (These people talk as if "intuitionistic proposition calculus" is a phrase that actually means something to normal humans!)
Roughly put, CHI says that types are theorems, and programs are proofs of those theorems. But what the hell does that even mean??
So far, I've figured this out:
Consider
id :: x -> x
. Its type says "given that X is true, we can conclude that X is true". Seems like a reasonable theorem to me.Now consider
foo :: x -> y
. As any Haskell programmer will tell you, this is impossible. You cannot write this function. (Well, without cheating anyway.) Read as a theorem, it says "given that any X is true, we can conclude that any Y is true". This is obviously nonsense. And, sure enough, you cannot write this function.More generally, the function's arguments can be considered "this which are assumed to be true", and the result type can be considered "thing that is true assuming all the other things are". If there's a function argument, say
x -> y
, we can take that as an assumption that X being true implies that Y must be true.For example,
(.) :: (y -> z) -> (x -> y) -> x -> z
can be taken as "assuming that Y implies Z, that X implies Y, and that X is true, we can conclude that Z is true". Which seems logically sensible to me.
Now, what the hell does Int -> Int
mean?? o_O
The only sensible answer I can come up with is this: If you have a function X -> Y -> Z, then the type signature says "assuming that it's possible to construct a value of type X, and another of type Y, then it is possible to construct a value of type Z". And the function body describes exactly how you would do this.
That seems to make sense, but it's not very interesting. So clearly there must be more to it than this...