隐藏构造函数但不导入导入类型

ram*_*ion 8 haskell module

我有一个内部模块,我想为其提供外部API

module Positive.Internal where

newtype Positive a = Positive { getPositive :: a }
  deriving (Eq, Ord)

-- smart constructor
toPositive :: (Num a, Ord a) => a -> Maybe (Positive a)
toPositive a | a <= 0    = Nothing
             | otherwise = Just $ Positive a
-- ...
Run Code Online (Sandbox Code Playgroud)

我想隐藏哑构造函数,并用单向模式替换它,这样用户仍然可以模拟匹配值,他们只需要使用智能构造函数来使用新值.

由于我希望模式和哑构造函数使用相同的名称,我需要隐藏哑构造函数以防止命名空间冲突.

但是,由于哑构造函数和类型共享名称,导入一切但是愚蠢的构造函数有点棘手.

目前我正在这样做,这可行:

{-# LANGUAGE PatternSynonyms #-}
module Positive
  ( module Positive.Internal, pattern Positive
  ) where

import Positive.Internal (Positive())
import Positive.Internal hiding (Positive)
import qualified Positive.Internal as Internal

pattern Positive :: a -> Positive a
pattern Positive a <- Internal.Positive a
Run Code Online (Sandbox Code Playgroud)

我可以通过使用合格的导入来简化我的导入,但我很好奇.

有没有办法在单个import语句中导入Positive.Internal除哑构造函数之外的所有内容?

我试过hiding (Positive(Positive)),但是它隐藏了类型和愚蠢的构造函数.我讨论过wiki,但是我没有注意到区分构造函数和hiding列表类型的方法.

leh*_*ins 3

如果我错了,请纠正我,但我几乎可以肯定这就是您正在寻找的:

\n\n
{-# LANGUAGE PatternSynonyms #-}\nmodule Positive\n  ( module Positive.Internal, pattern Positive, foo\n  ) where\n\nimport Positive.Internal hiding (pattern Positive)\nimport qualified Positive.Internal as Internal (pattern Positive)\n\npattern Positive :: a -> Positive a\npattern Positive a <- Internal.Positive a\n\nfoo :: Positive Int\nfoo = Internal.Positive 5\n
Run Code Online (Sandbox Code Playgroud)\n\n

Internal模块保持与迄今为止定义的方式相同。举个例子:

\n\n
module Negative where\n\nimport Positive\n\nbar :: Maybe Int\nbar = getPositive <$> toPositive 6\n
Run Code Online (Sandbox Code Playgroud)\n\n

让我们在 GHCi 中仔细检查一下:

\n\n
Prelude> :load Negative\n[1 of 3] Compiling Positive.Internal ( Positive/Internal.hs, interpreted )\n[2 of 3] Compiling Positive         ( Positive.hs, interpreted )\n[3 of 3] Compiling Negative         ( Negative.hs, interpreted )\nOk, modules loaded: Negative, Positive, Positive.Internal.\n*Negative> bar\nJust 6\n*Negative> getPositive foo\n5\n*Negative> :i Positive\nnewtype Positive a = Positive.Internal.Positive {getPositive :: a}\n    -- Defined at Positive/Internal.hs:3:1\ninstance [safe] Ord a => Ord (Positive a)\n  -- Defined at Positive/Internal.hs:4:17\ninstance [safe] Eq a => Eq (Positive a)\n  -- Defined at Positive/Internal.hs:4:13\n*Negative> :t Positive\n\n<interactive>:1:1: error:\n    \xe2\x80\xa2 non-bidirectional pattern synonym \xe2\x80\x98Positive\xe2\x80\x99 used in an expression\n    \xe2\x80\xa2 In the expression: Positive\n
Run Code Online (Sandbox Code Playgroud)\n