
On Oct 10, 2006, at 12:04 PM, Seth Gordon wrote:
data Secret a = Secret {password :: String, value :: a}
classify :: String -> a -> Secret a classify = Secret
declassify :: String -> Secret a -> Maybe a declassify guess (Secret pw v) | guess == pw = Just v | otherwise = Nothing
Put that in a module, do not export the Secret data type, and you're good to go. I'm unsure what a Monad is giving you....
I was just curious if I could do that within a monad.
If the answer to my question is "no, you can't", then I'll pick up the shattered pieces of my life and move on. :-)
I think you can. Your original monad is just a little too simplistic. Try something like this (untested): import Control.Monad.State type Password = String type Secret s a = State (Password -> Maybe s) a classify :: Password -> s -> Secret s () classify pw s = put (\x -> if x == pw then Just s else Nothing) declassify :: Password -> Secret s (Maybe s) declassify pw = get >>= \f -> return (f pw) runSecret :: Secret s a -> a runSecret m = runState m (const Nothing) Note how this relies on "opaque" functions to hide the secret. This wouldn't work if Haskell had intensional observation of functions, although you could still use a newtype in that case. Slightly related: I've sometimes wondered about a monadic API for cryptographic primitives. With compiler support you could do nifty things like make sure to use non-swappable memory for encryption keys and use fancy special purpose hardware for cryptographic primitives, if available. The API would give a nice way to ensure proper information hiding policy. Has anything like this been done or studied? Rob Dockins Speak softly and drive a Sherman tank. Laugh hard; it's a long way to the bank. -- TMBG