mercredi 15 juillet 2015

Can't show due to ambiguous type while using Data.Reflection in Haskell

I'm very new to Haskell and am trying to create a type that will represent any instance of Integral over some modulus. I found some example code online and am working with that, so my type definition looks like this:

data Zn n a = Zn !a !a

Most things are working as I'd like; I can show, add, subtract, etc.

instance (Integral a, Show a) => Show (Zn n a) where
   show (Zn n x) = printf "(%s mod %s)" (show (mod x n)) (show n)

instance (Integral a, Reifies n a) => Num (Zn n a) where
  Zn n x + Zn _ y = Zn n (mod (x + y) n)
  Zn n x - Zn _ y = Zn n (mod (x - y) n)
  Zn n x * Zn _ y = Zn n (mod (x * y) n)
  negate (Zn n x) = Zn n (n - x)
  abs = id
  signum x@(Zn _ 0) = x
  signum (Zn n _) = Zn n 1
  fromInteger x = Zn n (mod (fromInteger x) n)
    where n = reflect (Proxy :: Proxy n)


znToIntegral :: Integral a => Zn n a -> a
znToIntegral (Zn n x) = fromIntegral x

However, I can't show the results of arithmetic operations on these types. For example, in GHCi:

*Main> let x = Zn 5 3
*Main> x
(3 mod 5)
*Main> let y = Zn 5 7
(2 mod 5)
*Main> let z = x + y
*Main> z
<interactive>:6:1:
    No instance for (Integral a0) arising from a use of ‘print’
    The type variable ‘a0’ is ambiguous
    Note: there are several potential instances:
      instance Integral GHC.Int.Int16 -- Defined in ‘GHC.Int’
      instance Integral GHC.Int.Int32 -- Defined in ‘GHC.Int’
      instance Integral GHC.Int.Int64 -- Defined in ‘GHC.Int’
      ...plus 9 others
    In a stmt of an interactive GHCi command: print it

I've found this issue has come up in a number of other ways that I've tried to implement these numbers, and understanding how the Data.Reflection package works is giving me some troubles. I'd also be curious about any other implementations that seem more natural to others. I had originally tried doing something like

newtype Zn n a = Zn a

and switched because I thought that it would simplify things, which it hasn't in particular. Cheers!





Aucun commentaire:

Enregistrer un commentaire