尝试定义newType实例时出现模棱两可的错误

时间:2019-03-02 18:51:28

标签: haskell

我有以下代码

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

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

并出现以下错误:

  

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

中定义

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

2 个答案:

答案 0 :(得分:6)

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

Haskell语法对缩进敏感。特别是,类实例成员应该相对于单词instance缩进到右边,像这样:

instance Foo Bar where
    foo = ...

但是,在您的情况下,fmap的定义不以这种方式缩进。编译器将此表示您要声明一个“空”实例Functor MyList(其中“空”的意思是“未定义任何方法”-从技术上讲是合法的事情),然后在该实例之后,并单独定义一个名为fmap的函数。

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

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

instance Functor MyList where
    fmap f x = ...

答案 1 :(得分:5)

这是一个缩进错误。该代码应改为:

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

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