[ghc-steering-committee] Constructor synonyms, signatures on pattern synonym constructors

Christopher Allen cma at bitemyapp.com
Tue Mar 21 05:55:28 UTC 2017


I’m shepherding this two intertwined proposals, the Github discussions are located at:

- https://github.com/ghc-proposals/ghc-proposals/pull/41
- https://github.com/ghc-proposals/ghc-proposals/pull/42

The rendered proposals are located at time of review at:

- https://github.com/treeowl/ghc-proposals/blob/680d909a07b10b6a37a64adf174ee845783dc2a4/proposals/0000-constructor-synonyms.rst
- https://github.com/treeowl/ghc-proposals/blob/559df2865db8e4427b1f24d3100e59d61cb60e54/proposals/0000-bidir-constr-sigs.rst

Very briefly,

Proposal #41 is constructor synonyms. This would allow users to define variables with capitalized names and operators that begin with colons. They are meant to complement pattern synonyms. This example from the rendered proposal captures the idea and complementarity well I think:


pattern NF :: a -> NF a
pattern NF a <- UnsafeNF a

constructor NF :: NFData a => a -> NF a
constructor NF a = a `deepseq` UnsafeNF a

pattern Zero :: (Eq a, Num a) => a
pattern Zero <- ((== 0) -> True)

constructor Zero :: Num a => a
constructor Zero = 0

Proposal #42 would add type signatures for bidirectional pattern synonym constructor functions. Currently we can write this:

pattern Zero :: (Num a, Eq a) => a
pattern Zero <- ((== 0) -> True)  
  where
    Zero = 0

Per Feuer:

>The trouble in this case is that the Eq constraint from the pattern "infects" the constructor. So if I have a number type I can't test for equality, I can't use Zero to construct it.

It would permit writing things like this instead:

pattern Zero :: (Eq a, Num a) => a
pattern Zero <- ((== 0) -> True) where
  Zero :: Num a => a -- optional
  Zero = 0

This would prevent the pattern’s Eq constraint from “infecting” using Zero as a constructor, which doesn’t actually need Eq.


— My thoughts follow —

I think Richard’s right about how we’ll need to handle compatibility. I agree that the current warnings policy is a bit restrictive but it’s not worth getting people riled up over it.

I agree with Simon's comment on #42. I think we need to take seriously whether or not this proposal compromises the use-case of the naïve user consuming a library API that uses pattern constructors. Partly why I feel this is important is that as much debate as it draws, Haskell users consuming a lens-based API are able to cargo cult and move on with what they’re doing. I think pattern constructors should be held to a higher usability standard than lens due to looking like data constructors and being baked into the implementation.

This seems to clear up a limitation in expressiveness with few downsides as long as we avoid using holes and respect the community’s desires on backwards compatibility. Avoiding holes should make implementation easier and have fewer unpredictable behaviors down the road as well.


— My recommendation for the proposal —

My recommendation is that we accept both proposals. My reservation would be that it shouldn't have serious downsides for the existing users of pattern synonyms, be they authors or consumers.


Cheers,
Chris


More information about the ghc-steering-committee mailing list