The code below compiles just fine:
ecbEncryptRandomly :: RandomGen g => ByteString -> g -> (ByteString, g)
ecbEncryptRandomly bs gen = let key :: AES
(key, newGen) = random gen
in (ecbEncrypt key bs, newGen)
Now, I like things to be pretty, so I figured I'd just provide a type annotation for the entire tuple in my let
:
ecbEncryptRandomly :: RandomGen g => ByteString -> g -> (ByteString, g)
ecbEncryptRandomly bs gen = let (key, newGen) = random gen :: (AES, g)
in (ecbEncrypt key bs, newGen)
GHC doesn't like this one bit, and spits out the following error:
ECBCBCoracle.hs:32:56:
Could not deduce (g ~ g1)
from the context (RandomGen g)
bound by the type signature for
ecbEncryptRandomly :: RandomGen g =>
ByteString -> g -> (ByteString, g)
at ECBCBCoracle.hs:31:23-71
‘g’ is a rigid type variable bound by
the type signature for
ecbEncryptRandomly :: RandomGen g =>
ByteString -> g -> (ByteString, g)
at ECBCBCoracle.hs:31:23
‘g1’ is a rigid type variable bound by
an expression type signature: (AES, g1) at ECBCBCoracle.hs:32:49
Relevant bindings include
gen :: g (bound at ECBCBCoracle.hs:32:23)
ecbEncryptRandomly :: ByteString -> g -> (ByteString, g)
(bound at ECBCBCoracle.hs:32:1)
In the first argument of ‘random’, namely ‘gen’
In the expression: random gen :: (AES, g)
For some reason GHC seems to want to make the g
in the tuple a new type? The most perplexing thing about this is that when I use a typed hole, it suggests that I adopt g
as my type!
In other words, the following code:
ecbEncryptRandomly :: RandomGen g => ByteString -> g -> (ByteString, g)
ecbEncryptRandomly bs gen = let key :: AES
(key, _) = random gen
in (ecbEncrypt key bs, _)
Generates the following error:
ECBCBCoracle.hs:34:53:
Found hole ‘_’ with type: g
Where: ‘g’ is a rigid type variable bound by
the type signature for
ecbEncryptRandomly :: RandomGen g =>
ByteString -> g -> (ByteString, g)
at ECBCBCoracle.hs:31:23
Relevant bindings include
key :: AES (bound at ECBCBCoracle.hs:33:34)
gen :: g (bound at ECBCBCoracle.hs:32:23)
bs :: ByteString (bound at ECBCBCoracle.hs:32:20)
ecbEncryptRandomly :: ByteString -> g -> (ByteString, g)
(bound at ECBCBCoracle.hs:32:1)
In the expression: _
In the expression: (ecbEncrypt key bs, _)
In the expression:
let
key :: AES
(key, _) = random gen
in (ecbEncrypt key bs, _)
What's going on?