sdiehl / write-you-a-haskell

Building a modern functional compiler from first principles. (http://dev.stephendiehl.com/fun/)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Error in substitution algorithm

brianberns opened this issue · comments

The Substitutable instance for Type is currently defined as follows:

instance Substitutable Type where
  apply _ (TCon a)       = TCon a
  apply s t@(TVar a)     = Map.findWithDefault t a s
  apply s (t1 `TArr` t2) = apply s t1 `TArr` apply s t2

I believe the TVar case is incomplete. Consider the following substitution:

x <- y
y <- Int

If we apply this substitution to type variable x, we obtain y, when we should obtain Int. I think this case should instead recursively apply the substitution to the type found in the map.

For reference, here's an example where this problem occurs:

  • Unify types x -> x and y -> Int.
  • Input types x and y are unified, producing substitution x <- y.
  • This substitution is applied to output types x and Int, producing y and Int.
  • Output types y and Int are unified, producing substitution y <- Int.
  • The two substitutions are composed, producing x <- y, y <- Int.

One might argue instead that the composed substitution should be x <- Int, but this is not the current behavior of the algorithm.