Disallow exported function signatures with private type synonyms

As of 0.13.6 of the language this is a valid module:

module A (myInt) where

-- Notice that this type is _not_ exported
type PrivateInt = Int

myInt :: PrivateInt
myInt = 1

When generating documentation this causes purs docs to generate a broken link for the PrivateInt type in myInt's signature. Haskell has a similar situation, where you end up with Haddocks with “unclickable” types.

Disallowing this would obviously be a breaking change, but I’m curious if people are using this pattern in the wild and with what motivation. To me it seems that exporting a value/function with a signature involving a type synonym means that synonym is also relevant for the caller and thus should be exported.

Kind of a similar situation with synonyms in exported types:

module A (MyType) where

-- Notice that this type is _not_ exported
type Private = Int
type MyType = Private

already fails with

Error 1 of 1

  An export for MyType requires the following to also be exported:

    Private

Compiler Issue: https://github.com/purescript/purescript/issues/3879

3 Likes

Thanks for writing this up! I think the fact that public type synonyms are already prevented from referring to private type synonyms significantly strengthens the case for disallowing values (and any other declarations) from referring to private type synonyms.

I’ve only done this (not exported the synonym) by accident before, fwiw.

I’ve never understood the rules for this, so I assumed there was a bug somewhere. I guess it only applies to other type declarations? I suspect this will break a non-trivial amount of code though.