首页 > 解决方案 > 尝试定义 newType 的实例时出现模棱两可的错误

问题描述

我有以下代码

newtype MyList a = MyList { getList :: [a] } deriving Show

instance Functor MyList where
fmap f x = MyList (fmap f (getList x))

并得到以下错误:

它可以引用从 compile.hs:1:1 处的“Prelude”导入的“Prelude.fmap”(最初在“GHC.Base”中定义)或在 compile.hs:6:1 处定义的“Main.fmap”

如果我理解正确。如果我为新类型创建的新实例会如何影响 List [] 类型的现有实例,会如何。但为什么会发生呢?我认为 newtype 的目标是为同一类型创建不同的实例

标签: haskell

解决方案


不,您的实例不会“取代”或以其他方式影响常规列表实例。这只是语法混乱。

Haskell 语法对缩进很敏感。特别是,类实例成员应该相对于单词向右缩进instance,如下所示:

instance Foo Bar where
    foo = ...

但是,在您的情况下, of 的定义fmap并没有以这种方式缩进。编译器认为这意味着您正在声明一个“空”实例Functor MyList(其中“空”表示“不定义任何方法” - 这在技术上是合法的事情),然后在实例之后,并与它分开,您定义一个名为 的函数fmap

由于 Prelude 中已经定义了同名函数,因此编译器在您尝试调用它时不知道选择哪个函数 - 因此出现错误。

fmap要解决此问题,只需将定义向右缩进,如下所示:

instance Functor MyList where
    fmap f x = ...

推荐阅读