Explain why blackhole and blackhole () can have the same type
authorjim <jim@web>
Sat, 21 Mar 2015 14:45:35 +0000 (10:45 -0400)
committerLinux User <ikiwiki@localhost.members.linode.com>
Sat, 21 Mar 2015 14:45:35 +0000 (10:45 -0400)
exercises/assignment5_answers.mdwn

index 5425ac5..f62f8b4 100644 (file)
@@ -778,3 +778,5 @@ and that `bool` is any boolean expression.  Then we can try the following:
         match b with true -> y () | false -> n ()
 
     that would arguably still be relying on the special evaluation order properties of OCaml's native `match`. You'd be assuming that `n ()` wouldn't be evaluated in the computation that ends up selecting the other branch. Your assumption would be correct, but to avoid making that assumption, you should instead first select the `y` or `n` result, _and then afterwards_ force the result. That's what we do in the above answer.
+
+    Question: don't the rhs of all the match clauses in `match b with true -> y | false -> n` have to have the same type? How can they, when one of them is `blackhole` and the other is `blackhole ()`? The answer has two parts. First is that an expression is allowed to have different types when it occurs several times on the same line: consider `let id x = x in (id 5, id true)`, which evaluates just fine. The second is that `blackhole` will get the type `'a -> 'b`, that is, it can have any functional type at all. So the principle types of `y` and `n` end up being `y : unit -> 'a -> 'b` and `n : unit -> 'c`. (The consequent of `n` isn't constrained to use the same type variable as the consequent of `y`.) OCaml can legitimately infer these to be the same type by unifying the types `'c` and `'a -> 'b`; that is, it instantiates `'c` to the functional type had by `y ()`.