Exporting a Type Class for Type Signatures

In the crypto package, I have two functions
encrypt :: AESKey a => a -> Word128 -> Word128 decrypt :: AESKey a => a -> Word128 -> Word128
which are exported. I also have
class (Bits a, Integral a) => AESKey a
instance AESKey Word128 instance AESKey Word192 instance AESKey Word256
unexported which stops you using invalid keys. Someone has asked me to export AESKey as they want to write an explicit type signature for a function they are creating e.g. foo :: AESKey a => a -> Word128 -> Word128 foo x y = encrypt x y but this generates an error. Is there a way of allowing someone to use AESKey in a type signature but not allow them to declare new instances? Thanks, Dominic.

Hello Dominic, Monday, November 10, 2008, 10:56:37 PM, you wrote:
but this generates an error. Is there a way of allowing someone to use AESKey in a type signature but not allow them to declare new instances?
afaik module AES (class AESKey,...) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Bulat Ziganshin wrote:
Hello Dominic,
Monday, November 10, 2008, 10:56:37 PM, you wrote:
but this generates an error. Is there a way of allowing someone to use AESKey in a type signature but not allow them to declare new instances?
afaik
module AES (class AESKey,...)
This seems not to work on ghc6.8.2 at least. $ cat AClass.hs ; ghc AClass.hs module AClass (class A) where class A a where f :: a -> () instance A () where f = id AClass.hs:1:15: parse error on input `class' Alas I don't know of any way to export a class for type signatures without exporting it for instantiation (corrections welcome :) There is, however, a fairly canonical hack if you're only concerned with the correctness of the code in your own library. You create an extra (empty) public class which is only an indirection for the real private class; and make sure your library only uses the real class. This way, even though clients can make new instances on the public class, that won't affect your own code. If your goal is to try to ensure the correctness of client code (not just the correctness of the library code), this trick doesn't help though. -- Live well, ~wren

On Mon, Nov 10, 2008 at 1:56 PM, Dominic Steinitz
In the crypto package, I have two functions
encrypt :: AESKey a => a -> Word128 -> Word128 decrypt :: AESKey a => a -> Word128 -> Word128
which are exported.
I also have
class (Bits a, Integral a) => AESKey a
instance AESKey Word128 instance AESKey Word192 instance AESKey Word256
unexported which stops you using invalid keys.
Someone has asked me to export AESKey as they want to write an explicit type signature for a function they are creating e.g.
foo :: AESKey a => a -> Word128 -> Word128 foo x y = encrypt x y
but this generates an error. Is there a way of allowing someone to use AESKey in a type signature but not allow them to declare new instances?
Thanks, Dominic.
Is there anything wrong with:
encrypt :: AESKey -> Word128 -> Word128
data AESKey = Key128 Word128 | Key192 Word192 | Key256 Word256
Aside from the obvious that it's a breaking interface change. -Antoine

Dominic Steinitz
Is there a way of allowing someone to use AESKey in a type signature but not allow them to declare new instances?
I was going to suggest you export the class abstractly, that is, without its methods, so no-one could externally create an instance. But then I noticed that AESKey has no methods - it is just an alias for a combination of other classes - so that trick is insufficient. So, the other thing you could do is to introduce an indirection. module This (AESKey) where class (Bits a, Integral a) => AESKeyIndirection a -- un-exported class (AESKeyIndirection a) => AESKey a -- exported instance AESKeyIndirection Word128 instance AESKeyIndirection Word192 instance AESKeyIndirection Word256 instance AESKey Word128 instance AESKey Word192 instance AESKey Word256 Creating an instance of AESKey requires that you also create an instance of AESKeyIndirection. If only one of the names is available externally (exported), then instances can only be created internal to the module. Regards, Malcolm
participants (5)
-
Antoine Latter
-
Bulat Ziganshin
-
Dominic Steinitz
-
Malcolm Wallace
-
wren ng thornton