4

I've begun reading the book Thinking With Types which is my first foray into type level programming. The author provides an exercise and the solution, and I cannot understand how the solution provided is correct.

The exercise is

enter image description here

I attempted to solve this exercise with the following

productToRuleMine :: (b -> a, c -> a) -> Either b c -> a
productToRuleMine (f, _) (Left b) = f b
productToRuleMine (_, g) (Right c) = g c

productFromRuleMine :: (Either b c -> a) -> (b -> a, c -> a)
productFromRuleMine f = (f . Left, f . Right)

productToRuleMine . productFromRuleMine = id

I feel this is a valid solution, however the book gives a different solution that doesn't seem to type check, leading me to believe my overall understanding is flawed

productToRuleBooks :: (b -> a) -> (c -> a) -> (Either b c) -> a
productToRuleBooks f _ (Left b) = f b
productToRuleBooks _ g (Right c) = g c

productFromRuleBooks :: (Either b c -> a) -> (b -> a, c -> a)
productFromRuleBooks f = (f . Left, f . Right)

The only way I can get the books answer to type check is the following:

(uncurry productToRule1 . productFromRule1) = id

since the type signatures alone don't line up

(Either b c -> a) -> (b -> a  ,   c -> a)
                     (b -> a) -> (c -> a) -> (Either b c) -> a

So the question I have is, is my solution incorrect? Why does the books type signature for productToRuleBooks accept as it's first and second arguments the functions b -> a and c -> a when it's my understanding that x (multiplication) from algebra equates to the (,) in types, so why doesn't the books answer have (b -> a, c -> a) as the first argument?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Shane Unger
  • 378
  • 1
  • 7
  • 5
    Your solution is correct, you just used tuples `(a,b)` as arguments. They're equivalent. In fact, that's a good exercise: show that if `(a, b) -> c` then `a -> (b -> c)` too, and vice versa. – AJF May 12 '19 at 22:47
  • 1
    I don't think there's anything wrong with your solution or your understanding. Your solution and the book's are identical except that the book's version of `productToRuleMine` is curried, and yours is not. Without seeing the book I can't say why they chose to do it that way, since as you said, tuples are the CH equivalent of multiplication. (According to my own limited understanding.) – Robin Zigmond May 12 '19 at 22:48
  • 1
    @RobinZigmond The multiplication bit is the combinatoric interpretation. The logical interpretation is conjunction. The logical tautology being proved here, by pure Curry-Howard, is `(b -> a /\ c -> a) <-> (b \/ c -> a)`. The interpretation `a^b * a^c = a^(b + c)` is combinatoric. The Curry-Howard comes in here to show that it is possible for a program to prove that equality. – HTNW May 12 '19 at 23:30
  • 3
    Yes your solution is essentially the same as the books. By the way, this is not technically a proof, but a statement of the theorem -- to prove it, you need to show *how* `productToRule . productFromRule` rewrites to `id`. – luqui May 13 '19 at 06:29

0 Answers0