键入私人类型的签名

Mat*_*hid 7 haskell types

好的,所以这是一个不起眼的语言角落:

Haskell允许您导出标识符,该标识符的类型签名提到导出的类型.究竟是什么语义?

例如,假设我有

module Foobar (bar) where

data Foo = ...

bar :: String -> Foo
Run Code Online (Sandbox Code Playgroud)

Foo不会导出,bar而是.但是bar提到的类型Foo.许多编程语言都不允许你这样做,但Haskell确实如此.

所以现在怎么办?似乎我可以打电话bar,但是结果不能做多少.特别是,我(大概)不能说出结果类型的名称,这有点奇怪.据推测,如果模块导出了一些Foo作为输入的函数,我应该能够将那些以我的结果作为输入的函数调用...但是在类型签名中我不能这么说.

当然,做上述事情并不是一个好主意 ; 我不打算在实际代码中这样做.我只是好奇它实际上了什么.

J. *_*son 3

如果 Haskell 禁止您导出自己的推断类型,这可能会更有趣Foo——这将使这里的情况表现得更像存在类型,这对于模块系统来说是一个好主意。

相反,类型信息会泄漏。实例信息也是如此。对于“例如”以下内容是不安全的

module Foo ( foo ) where

  data Foo ...
    deriving (Data, Typeable) -- for internal use

  foo :: Foo -> IO ()
Run Code Online (Sandbox Code Playgroud)

因为使用foo将允许“邪恶”用户联合起来,Data.Data.fromConstr ...即使Foo用户不应该能够生成Foo值。

-- mkFoo :: Constr -> Foo       (except I have to let this be inferred)
mkFoo c = out where
  out     = fromConstr c
  ignored = foo out
Run Code Online (Sandbox Code Playgroud)

最终,我认为这是一个糟糕的 API。如果要强调类型的使用而不允许用户构造它,请导出该类型。