It might be more interesting if Haskell were to forbid you from exporting types of your own which infer Foo
s---this would make the situation here behave a bit more like existential typing which is A Good Idea for module systems.
Instead, the type information leaks. So does the instance information. For "instance" the following is unsafe
module Foo ( foo ) where
data Foo ...
deriving (Data, Typeable) -- for internal use
foo :: Foo -> IO ()
since using foo
will allow an "evil" user to unify Data.Data.fromConstr ...
with Foo
even if users are not supposed to be able to generate Foo
values.
-- mkFoo :: Constr -> Foo (except I have to let this be inferred)
mkFoo c = out where
out = fromConstr c
ignored = foo out
Ultimately, I'd consider this to be a poor API. If you want to emphasize the use of a type without allowing the user to construct it, export the type.