尝试定义newType的实例时出现不明确的错误

oriaj 0 haskell

我有以下代码

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

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

并得到以下错误:

它可以指代"Prelude.fmap"从compile.hs"前奏"输入:1:6:1:1或1"Main.fmap",(和最初在"GHC.Base"中定义)在compile.hs定义

如果我明白的话.如果我为新类型创建的新实例会影响List []类型的现有实例.但为什么会发生呢?我认为newtype的目标是为同一类型创建一个不同的实例

Fyodor Soiki.. 5

不,您的实例不会"取代"或以其他方式影响常规列表实例.这仅仅是语法混乱.

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

instance Foo Bar where
    foo = ...

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

由于Prelude中已定义了具有相同名称的函数,因此编译器在您尝试调用时不知道要选择哪个函数 - 因此出错.

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

instance Functor MyList where
    fmap f x = ...