如何忽略标准模块?

How to disregard a standard module?

作为练习,我正在尝试实现我自己的标准 Functor 版本,在本例中为 Either

我的代码看起来与标准定义相似:

instance Functor (Either a) where
  fmap _ (Left x) = Left x
  fmap f (Right y) = Right (f y)

当我尝试编译它时出现以下错误:

ghc --make either.lhs
[1 of 1] Compiling Main             ( either.lhs, either.o )

either.lhs:14:12: error:
    Duplicate instance declarations:
      instance Functor (Either a) -- Defined at either.lhs:14:12
      instance Functor (Either a) -- Defined in ‘Data.Either’
make: *** [hs] Error 1

编译器发现与 Data.Either 中定义的标准实例存在冲突。尽管我实际上并没有在我的代码中导入 Data.Either 模块。我想编译和测试我自己的 Functor 实现——有没有什么方法可以让我从编译器中隐藏 Data.Either 以避免冲突?

您有两个选择:

定义你自己的 Either.

module Foo where
import Prelude hiding (Either)

data Either a b = Left a | Right b

instance Functor (Either a) where ...

定义你自己的 Functor.

module Bar where
import Prelude hiding (Functor)

class Functor f where
  fmap :: (a -> b) -> f a -> f b

instance Functor (Either a) where ...

正如您发现的那样,您也可以只编造不冲突的名称,而不是向 Prelude 隐藏内容。但是学会隐藏东西非常重要;例如,您会看到很多程序都这样做:

import Control.Category
import Prelude hiding (id, (.))

那是因为那些程序想要使用 Control.Category 中更通用的 id(.) 而不是前奏曲中的那些。