简体   繁体   中英

Polymorphic reasoning

I am learning Haskell and in internet I've found is paper from Philip Wadler.
I read it and did not understand at all, but it somehow connects to polymorphic function.

For example:

polyfunc :: a -> a -> a

It is a polymorphic function of any type.

What is the free theorem in connection of the example polyfunc ?

I feel like if I actually understood that paper then any code I wrote would be coauthored by God.

My best guess for this problem though is that all polyfunc can do is either always return the first argument or always return the second argument. So there are actually only two implementations of polyfunc ,

polyfuncA a _ = a
polyfuncB _ b = b

The paper gives you a way to prove that claim.

This is a very important concept. For example, I've been involved in data quality research previously. This free theorem says that there is no function which can select the best data from two arbitrary pieces of data. We have to know something more. Its actually a no-brainer that I was surprised to find some people willing to overlook.

I've never really understood the algorithm laid out in that paper either, so I thought I would try to figure it out.

(1) Type of function in question
f :: a -> a -> a

(2) Rephrasing as a relation
f : ∀X. X -> X -> X

(3) By parametricity
(f, f) ∈ ∀X. X -> X -> X

(4) By definition of ∀ on relations
for all Q : A <=> A',
  (fA, fA') ∈ Q -> Q -> Q

(5) Applying definition of -> on relations to the first -> in (4)
for all Q : A <=> A',
  for all (x, x') ∈ Q,
    (fA x, fA' x') ∈ Q -> Q

(6) Applying definition of -> on relations to (5)
for all Q : A <=> A',
  for all (x, x') ∈ Q,
    for all (y, y') ∈ Q,
      (fA x y, fA' x' y') ∈ Q

At this point I was done expanding the relational definition, but wasn't sure how to get this back from relations into terms of functions and types, so I went and found a webapp that will automatically derive the free theorem for a type . I won't spoil (yet) what result it gives, but looking at it did help me figure out the next step in my proof.

The next step is to get back into function-land from relation-land, by noting that Q can be the type of any function at all and this will still hold.

(7) Specializing Q to a function g :: p -> q
for all p, q
  for all g :: p -> q
    where g x = x'
      and g y = y'
        g (f x y) = f x' y'

(8) By definitions of x' and y'
for all p, q
  for all g :: p -> q
    g (f x y) = f (g x) (g y)

That looks true, right? It is equivalent to use g to transform both elements and then let f choose between them, or to let f choose an element and then transform it with g . By parametricity, f can't change whether it chooses the left or right element based on anything that g does.

Of course the claim given in trevor cook's answer is true: f must either always choose its first argument, or always choose its second. I'm not sure whether the free theorem I derived is equivalent to that, or is a weaker version of it.


And incidentally, this is a special case of something that is already covered explicitly in the paper. It gives the theorem for

k :: x -> y -> x

which of course is the same as your function f , where x ~ a and y ~ a . The result that it gives is the same as the one I described:

for all a, b, x, y
  a (k x y) = k (a x) (b y)

if we choose b=a to make the two results equivalent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM