<div dir="ltr"><div>There are artifacts of old Haskell standards that are a matching against integer value (2 + 2 = 5) and a matching against arithmetic expression (f (n+1) = f n).</div><div><br></div><div>Both are interesting in requiring a class over type to match.</div><div><br></div><div>f 10 = 11 has type f :: (Eq a1, Num a1, Num a2) => a1 -> a2</div><div><br></div><div>f (n+1) = f n has type f :: Integral t1 => t1 -> t2</div><div><br></div><div>In that vein it is possible to add non-linear patterns by adding an equality constraint on the non-linear matches.</div><div><br></div><div>E.g., f x x = x would have type f :: Eq a => a -> a -> a</div><div><br></div><div>For example:</div><div><br></div><div>data Logic = True | False | Not Logic | Or Logic Logic | And Logic Logic deriving Eq</div><div><br></div><div>simplify (And x x) = simplify x</div><div>simplify (Or x x) = simplify x</div><div>simplify (Not (Not x)) = simplify x</div><div>simplify x = x</div><div><br></div><div>Patterns like that are common in simplification/optimization rules. Also, by making them legal, it would be possible to use them in Template Haskell to make better embedded languages.</div><div><br></div><div>On the implementation side, it can be implemented much like the (n+k) pattern. I also think that pattern matching completeness checker should not change.</div><div><br></div><div>What would you say?</div></div>