为什么我在定义实例时遇到模糊的发生错误?

问题描述:

我有一个类型Foo并希望把它的Show一个实例,这样我就可以在ghci中使用它:为什么我在定义实例时遇到模糊的发生错误?

data Foo = Foo 

instance Show Foo where 
show Foo = "Foo" 

然而,当我尝试使用它,我得到一个模棱两可发生错误:

ghci> show Foo 
<interactive>:4:1: 
    Ambiguous occurrence `show' 
    It could refer to either `Main.show', defined at Foo.hs:4:1 
          or `Prelude.show', 
          imported from `Prelude' at Foo.hs:1:1 
          (and originally defined in `GHC.Show') 

为什么?我只是定义了属于类型类的函数,不是吗?

+0

注意:这个问题是,就像[我的另一个](https://*.com/questions/35855170/why-shouldnt-i-mix-tabs-and-spaces),打算是一个最小的通用其中一个更常见的Haskell问题的变体。 – Zeta

TL; DR:缩进实例绑定。


启用警告,你会发现,你没有实现实例操作show,而是一个新的功能具有相同名称:

Foo.hs:3:10: Warning: 
    No explicit implementation for 
     either `showsPrec' or `Prelude.show' 
    In the instance declaration for `Show Foo' 

因此现在有两个show s。 Main.show(你刚刚意外定义的那个)和Prelude.show(你想要使用的类)。

我们可以验证通过查看它们的类型(尽管我们需要完全限定他们的名字):

ghci> :t Main.show 
Main.show :: Foo -> [Char] 
ghci> :t Prelude.show 
Prelude.show :: Show a => a -> String 

那是因为你的where绑定需要缩进,就像你会缩进他们通常功能。即使只有一个空间就足够了:

instance Show Foo where 
show Foo = "Foo" 

请记住,Haskell使用空格来分隔块。只问自己:where什么时候会停止呢?