Type signature with private type
OK, so here's an obscure corner of the language:
Haskell allows you to export an identifier who's type signature mentions a type that is not exported. What exactly is the semantics of this?
For example, suppose I have
module Foobar (bar) where
data Foo = ...
bar :: String -> Foo
Foo
is not exported, while bar
is. The type of bar
mentions Foo
, though. Many programming languages wouldn't let you do this, but Haskell does.
So what now? It seems that I can call bar
, but then can't do much with its result. I particular, I (presumably) cannot utter the name of the result type, which is kinda weird. Presumably if the module exported some functions that take Foo
as input, I ought to be able to call those with my result as input... yet all the whole I can't say so in a type signature.
For sure, doing something like the above is not a good idea; I'm not proposing to do this in actual code. I'm just curious as to what it actually does.
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.
链接地址: http://www.djcxy.com/p/20196.html上一篇: 为什么DataGridRow IsSelected绑定在DataGrid上不起作用
下一篇: 输入私人类型的签名