Haskell中的重载(show和num)

Haskell中的重载(show和num),haskell,overloading,Haskell,Overloading,我正在haskell学习重载,我在尝试重载show和num类时遇到了一些问题。我使用一个新的递归数据,我有以下函数: module Nat where data Nat = Zero | Suc Nat --Zero = 0 --Suc (Suc zero) = 1 --suc (suc(suc zero)) = 2 --nat2int:: Nat -> Int nat2int Zero = 0 nat2int (Suc x) = 1 Prelude.+ nat2int x

我正在haskell学习重载,我在尝试重载show和num类时遇到了一些问题。我使用一个新的递归数据,我有以下函数:

    module Nat where
data Nat = Zero | Suc Nat
--Zero = 0
--Suc (Suc zero) = 1
--suc (suc(suc zero)) = 2 
--nat2int:: Nat -> Int

nat2int Zero = 0
nat2int (Suc x) = 1 Prelude.+ nat2int x

--suma: Nat -> Nat -> Nat
suma Zero b = b --addition
suma (Suc a) b = Suc (suma a b)

--producto: Nat -> Nat -> Nat
producto Zero _ = Zero --product
producto (Suc m) n = suma n (producto m n)
这些函数工作正常,但当我尝试创建两个实例时:

module Sobrecarga where 
import Nat
instance Show Nat where
show Zero = "0"
show (Suc x) = Prelude.show (nat2int (Suc x))
instance Num Nat where
(+) a b = suma a b
(*) a b = producto a b
我收到了这2条警告,如果您尝试使用show、sumar o producto,ghci编译器会给我一个错误:

Sobrecarga.hs:3:10: warning: [-Wmissing-methods]
    * No explicit implementation for
        either `showsPrec' or `Prelude.show'
    * In the instance declaration for `Show Nat'
  |
3 | instance Show Nat where
  |          ^^^^^^^^

Sobrecarga.hs:8:10: warning: [-Wmissing-methods]
    * No explicit implementation for
        `Prelude.+', `Prelude.*', `abs', `signum',
        `fromInteger', and (either `negate' or `-')
    * In the instance declaration for `Num Nat'


*Sobrecarga> Zero + Zero
<interactive>:65:6: error:
    Ambiguous occurrence `+'
    It could refer to either `Prelude.+',
                             imported from `Prelude' at Sobrecarga.hs:1:8-17
                             (and originally defined in `GHC.Num')
                          or `Sobrecarga.+', defined at Sobrecarga.hs:7:1
Sobrecarga.hs:3:10:警告:[-Wmissing方法]
*没有针对的显式实现
“showsPrec”或“Prelude.show”
*在“Show Nat”的实例声明中
|
3 |实例显示Nat的位置
|          ^^^^^^^^
Sobrecarga.hs:8:10:警告:[-Wmissing方法]
*没有针对的显式实现
`前奏曲+,'Prelude.*','abs','signum',,
`fromInteger',和(否定或“-”)
*在'Num Nat'的实例声明中
*Sobrecarga>零+零
:65:6:错误:
歧义出现“+”
它可以指“前奏曲+”,
从Sobrecarga的“前奏曲”中导入。hs:1:8-17
(最初在“GHC.Num”中定义)
或“Sobrecarga.+”,定义于Sobrecarga.hs:7:1

您有任何解决方案来修复无歧义吗?

这些警告主要是由于实例定义中的错误缩进造成的。而不是

instance Show Nat where
show Zero = "0"
show (Suc x) = Prelude.show (nat2int (Suc x))
你应该写

instance Show Nat where
  show Zero = "0"
  show (Suc x) = Prelude.show (nat2int (Suc x))
对于
Num
实例也是如此。那么您的
Num
实例也缺少很多方法

instance Num Nat where
 (+) a b = suma a b
 (*) a b = producto a b

 abs         = ?    
 signum      = ?
 fromInteger = ?
 negate      = ?
你需要实现所有这些。一些进一步的观察

--Suc (Suc zero) = 1
--suc (suc(suc zero)) = 2 
我知道这被注释掉了,但请记住Haskell是区分大小写的。因此,
Suc
Zero
必须大写

nat2int Zero = 0
nat2int (Suc x) = 1 Prelude.+ nat2int x
写下您的类型签名是个好主意,而且您不需要
序言。

show Zero = "0"
show (Suc x) = Prelude.show (nat2int (Suc x))
同样,去掉前奏曲。,也没有必要考虑零和非零的情况。这就足够了

show nat = show (nat2int nat)
或者使用组合

show = show . nat2int

您需要进一步缩进函数。您定义了空实例
instance。。其中
后跟与实例无关的顶级函数
show、(+)、…
。实例中的函数必须比
instance…
i
缩进得更多。如果您这样做,您可以删除
前奏。
限定符,之所以需要这些限定符,是因为您使用相同的限定符定义了一个不相关的函数。我投票将其作为一个简单的印刷修复关闭,但请不要认为这意味着这是一个糟糕的问题!很高兴你得到了一个简单的答案。
Num
对于
Nat
,没有一个很好的
Num
实例,因为你不能定义
否定。