Is there a general algorithm to flatten nested lhs cases in functional programming languages?

Viewed 168

Functional programming languages, like Haskell, allow users to define functions using an equational notation, where the left-hand side has several pattern arguments that can be matched, with arbitrary many nests. For example:

(fun (Ctr A A) (Foo (Tic X)) a b c d e) = a
(fun (Ctr A B) (Foo (Tac Y)) a b c d e) = b
(fun (Ctr B A) (Bar (Tic X)) a b c d e) = c
(fun (Ctr B B) (Bar (Tac Y)) a b c d e) = d
(fun x         y             a b c d e) = (df x y a b c d e)

Suppose, though, that you wanted to compile that function to a language that didn't allow nested pattern matches. That is, you'd have to flatten these clauses into a series of functions that, grouped together, would be equivalent to fun. For example, in the case above, you could flatten it as follows:

(fun (Ctr x1 x2) (Foo x3) a b c d e) = (fun_0 x1 x2 x3 a b c d e)
(fun (Ctr x1 x2) (Bar x3) a b c d e) = (fun_1 x1 x2 x3 a b c d e)
(fun x           y        a b c d e) = (df x y a b c d e)

(fun_0 A A (Tic x0) a b c d e) = (fun_0_0 x0 a b c d e)
(fun_0 A B (Tac x0) a b c d e) = (fun_0_1 x0 a b c d e)
(fun_0 x y z        a b c d e) = (df (Ctr x y) (Foo z) a b c d e)

(fun_1 B A (Tic x0) a b c d e) = (fun_1_0 x0 a b c d e)
(fun_1 B B (Tac x0) a b c d e) = (fun_1_1 x0 a b c d e)
(fun_1 x y z        a b c d e) = (df (Ctr x y) (Bar z) a b c d e)

(fun_0_0 X a b c d e) = a
(fun_0_0 x a b c d e) = (df (Ctr A A) (Foo (Tic x)) a b c d e)
(fun_0_1 Y a b c d e) = b
(fun_0_1 x a b c d e) = (df (Ctr A B) (Foo (Tac x)) a b c d e)
(fun_1_0 X a b c d e) = c
(fun_1_0 x a b c d e) = (df (Ctr B A) (Bar (Tic x)) a b c d e)
(fun_1_1 Y a b c d e) = d
(fun_1_1 x a b c d e) = (df (Ctr B B) (Bar (Tac x)) a b c d e)

My question is: is there a general algorithm that flattens nested lhs pattern matches into un-nested clauses, with the lowest amount of clauses possible?

1 Answers

Chapter 4 of Simon PJ's "The Implementation of Functional Programming Languages" is dedicated to this topic. See here for a pdf: https://www.microsoft.com/en-us/research/wp-content/uploads/1987/01/slpj-book-1987-small.pdf

The chapter is coauthored by Phil Wadler, one of the designers of Haskell.

While this book uses a pre-Haskell style syntax, the ideas carry over. When GADTs, pattern-match completeness etc are involved, you'll need to look at newer papers; but the basic idea/algorithms remain the same.

Related