如何导出类型类?

时间:2015-08-10 20:46:50

标签: haskell module typeclass

我正在创建一个文件Common.hs,它导出我常用的函数。它还用我喜欢的版本取代了Prelude的一些功能:

-- Common.hs
module Common 
import qualified Prelude as Prelude
import qualified Data.Foldable as Foldable

sum      = Foldable.sum  -- I want to replace Prelude's sum
print    = Prelude.print -- I want to export Prelude's print
type Int = Prelude.Int   -- I want to export Prelude's Int
... etc (huge list) ...

这样,每当我创建一个新的Haskell文件时,我只需导入Common并使用-XNoImplicitPrelude进行编译:

-- Test.hs
import Common
main = print (sum [1,2,3]) -- will be the `sum` version I want

这种方法似乎有效,但我无法确定如何导出类型类:

-- Test.hs
import Common
import Prelude (Show)

data Foo = Foo Int Int deriving Show

main = print (Foo 1 2)

注意我必须手动导入Prelude的节目。是否可以Common.hs导出它?

1 个答案:

答案 0 :(得分:10)

您必须明确地重新导出类型类(意味着您还必须明确地导出其他所有内容),即

你的序曲:

module CustomPrelude (
  sum,
  product,
  Prelude.IO,
  Prelude.String,
  Prelude.print,
  Prelude.Show,
  Prelude.show,
  (Prelude.$),
  Prelude.Int,
  (++)
  )
where

import qualified Prelude
import Data.Foldable
import Data.Monoid

(++) :: Monoid m => m -> m -> m
(++) = mappend

用法:

{-# LANGUAGE NoImplicitPrelude #-}
module PreludeTest where

import CustomPrelude

data A x = A x x

instance Show x => Show (A x) where
    show (A x y) = "A " ++ show x ++ " " ++ show y

main :: IO ()
main = print $ A (1::Int) 2

为了节省一些打字(并在编辑时保持理智),您可能希望这样做: A)将新的前奏分成几个专门的文件 B)模块导出,因此您不必明确重复所有内容

E.g:

module CustomPrelude.Classes (Show,show,Functor,fmap, Monoid,mempty,mappend, Monad,return,(>>=))
where

import Data.Monoid
module CustomPrelude.Functions (
  module ReExport,
  Prelude.print,
  Prelude.IO, -- ok these technically aren't functions, but I didn't want to make yet another module just for demonstration purposes
  Prelude.String,
  Prelude.Int,
  (Prelude.$),
  (++)
)
where

import qualified Prelude
import Data.Foldable as ReExport
import Data.Traversable as ReExport
import Data.Monoid as ReExport


(++) :: Monoid m => m -> m -> m
(++) = mappend
module CustomPrelude (
  module P
  )
where

import CustomPrelude.Classes as P
import CustomPrelude.Functions as P

请注意,您可以通过在导入时将重新导出的模块重命名为相同的名称来节省大量的打字工作。