title: Combining patterns
body: <p>Consider the following data type and pattern synonyms:</p>
  
  <pre><code>{-# LANGUAGE PatternSynonyms, NamedFieldPuns #-}
  
  data Foo = Foo {
        a :: Int
      , b :: String
      , c :: Maybe Bool
  }
  
  pattern Bar a b &lt;- Foo { a, b }
  pattern Baz c &lt;- Foo { c }
  </code></pre>
  
  <p>I'd like to match a <code>Foo</code> but get all of <code>a</code>, <code>b</code>, and <code>c</code>. Something like this (invalid Haskell):</p>
  
  <pre><code>showit :: Foo -&gt; String
  showit (Bar a b &amp; Baz c) = show a ++ b ++ show c
  </code></pre>
  
  <p>One option is to use a <code>ViewPattern</code>:</p>
  
  <pre><code>dup :: a -&gt; (a, a)
  dup a = (a, a)
  
  showall' :: Foo -&gt; String
  showall' (dup -&gt; (Bar a b, Baz c)) = show a ++ b ++ show c
  </code></pre>
  
  <p>But this results in a non-exhaustive match warning. But we know that <code>Bar</code> and <code>Baz</code> are irrefutable so matching each is also irrefutable.</p>
  
  <p>How can this be expressed without a compiler warning?</p>
  
  <p>The motivation for this is to have fine-grained pattern synonyms against fields of a large data type and allow callers to extract just the desired fields similar to records with <code>NamedFieldPuns</code>. Pattern synonyms don't yet support record syntax, but it's in the works : <a href="https://ghc.haskell.org/trac/ghc/ticket/8582" rel="nofollow noreferrer">https://ghc.haskell.org/trac/ghc/ticket/8582</a></p>
  
  <p>In my case I cannot expose the constructor from the module since I'm using the "smart-constructor" pattern, and hence cannot give callers the benefit of record pattern matching with <code>NamedFieldPuns</code>.</p>
  
  <p>See <a href="https://stackoverflow.com/a/25161749/3198498">https://stackoverflow.com/a/25161749/3198498</a> as the inspiration. I'm trying to expand the idea in that answer to allow callers to arbitrarily extract <em>n</em> of <em>m</em> fields, for a largish <em>m</em>.</p>
  
  <p>Edit: It turns out there is a rather broad problem with <code>PatternSynonyms</code> and exhaustiveness checks : <a href="https://ghc.haskell.org/trac/ghc/ticket/10339" rel="nofollow noreferrer">https://ghc.haskell.org/trac/ghc/ticket/10339</a>
  This seems to make pattern synonyms used as field extractors very unpleasant when compiling with warnings enabled.</p>