2

I'm learning Overloading in haskell and I have a few problems trying to overload show and num clases. I work with a new recursive data and I have this functions:

    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)

The functions work correctly, but when i try to create 2 instances:

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

i got this 2 warnings and if y try to use show, sumar o producto, the ghci compiler give me an error:

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

Have you any solution to fix the amibiguity?

duplode
  • 33,731
  • 7
  • 79
  • 150
  • 2
    You need to indent your functions more. You defined _empty_ instances `instance .. where` followed by top-level functions `show,(+),...` which are unrelated to the instance. The functions inside the instances must be more indented than the `i` of `instance ...`. If you do that, you can remove the `Prelude.` qualifiers, which were needed only because you defined an unrelated function with the same same. – chi Dec 03 '18 at 12:56
  • I’m voting to close this as a simple typographical fix, but please don’t take that to mean it was a bad question! Glad you got a simple answer. – Davislor Dec 03 '18 at 14:29
  • There isn't really a good `Num` instance for `Nat`, because you can't define `negate`. – chepner Dec 03 '18 at 14:44

1 Answers1

3

Those warnings are primarily a result of bad indentation in the definition of your instances. Instead of,

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

you should write,

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

and similarly for your Num instance. Then your Num instance is also missing quite a few methods,

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

 abs         = ?    
 signum      = ?
 fromInteger = ?
 negate      = ?

You need to implement all those. Some further observations.

--Suc (Suc zero) = 1
--suc (suc(suc zero)) = 2 

I know this is commented out, but keep in mind Haskell is case-sensitive. So Suc and Zero must be capitalised.

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

It's a good idea to write down your type signature, furthermore you do not need that Prelude..

show Zero = "0"
show (Suc x) = Prelude.show (nat2int (Suc x))

Same here, get rid of Prelude., also there's no point in considering the case for zero and non-zero. It's enough to do,

show nat = show (nat2int nat)

or alternatively using composition,

show = show . nat2int