3

When using powModfrom the Math.NumberTheory.Powers.Modular library, the Haskell compiler or interpreter gives the following warning:

warning: [-Wdeprecations] In the use of ‘powMod’ (imported from Math.NumberTheory.Powers.Modular): Deprecated: "Use Data.Mod or Data.Mod.Word instead"

I had the following function:

cypher n e m = powMod m e n

So I try to convert it to the recommended new library Data.Mod, substituting the powMod function by the (^%) operator:

cypher n e m = m ^% e :: Mod n

But then, the following error arises, and I don't know how to correct it:

• Couldn't match expected type ‘Mod n1’ with actual type ‘p2’
    because type variable ‘n1’ would escape its scope
  This (rigid, skolem) type variable is bound by
    an expression type signature:
      forall (n1 :: GHC.Types.Nat). Mod n1
    at RSA-cyphering.hs:43:26-30
• In the first argument of ‘(^%)’, namely ‘m’
  In the expression: m ^% e :: Mod n
  In an equation for ‘cypher’: cypher n e m = m ^% e :: Mod n

How can be used the type Mod n inside a function when the module n is taken from an argument to the function?

enrique
  • 492
  • 3
  • 11

1 Answers1

3

You use SomeMod:

cypher :: Natural -> Integer -> Integer -> SomeMod
cypher n e m = (m `modulo` n) ^ e
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • Ok, `powSomeMod` then, and the functions for "Unknown modulo" from Math.NumberTheory.Moduli.Class. Then I understand that Data.Mod can only be used for modulo which is known at coding time, because `Mod n` is a type and it can not be created dynamically inside a function at execution time, is this correct?. – enrique Jun 26 '21 at 10:30
  • 1
    @enrique You can use `powSomeMod` if you want, but `(^)` also works, is more readable, and magically becomes `powSomeMod` when optimizations are on, so I'd stick with the code as suggested here. Yes, `Mod n` can only be used directly when `n` is known at compile time; but `SomeMod` is an existential wrapper around `Mod n` that lets you create a `Mod n` dynamically inside a function at execution time. – Daniel Wagner Jun 26 '21 at 13:52
  • But my original function gives an `Integer` (or any `Integral`). How can I get it from a `SomeMod` value? (what pattern matching?). – enrique Jun 26 '21 at 15:45
  • @enrique Have you read the documentation? What did you try? What went wrong? – Daniel Wagner Jun 26 '21 at 16:02
  • ``SomeMod c = (m `modulo` n) ^ e -- Should give a (Mod m) value.`` – enrique Jun 27 '21 at 10:33
  • The previous does not work, but I think I got it now, this gives an `Integer`: ``cypher n e m = case (m `modulo` n) of SomeMod k -> getVal $ k ^% e`` – enrique Jun 28 '21 at 15:44