I finally (think I) understand monads well enough to make one up:

module Secret (Secret, classify, declassify)
where

data Secret a = Secret a

classify :: a -> Secret a
classify x = Secret x

declassify :: Secret a -> String -> Maybe a
declassify (Secret x) "xyzzy" = Just x
declassify (Secret x) _ = Nothing

instance Monad Secret where
    return = classify
    (Secret x) >>= f = f x

The nice thing about this is that (correct me if I'm wrong) clients of the module can't sneak information out of the monad without either using the right password or by using one of the unsafe*IO methods. (Or by running the program in a debugger. But you get the idea.)

The not-so-nice thing is that the literal text of the password is baked into the data definition. I'd like to have a more general version of Secret that allows someone to pass the password in when constructing a secret, and preserves that password when "return" is used, but doesn't let the second argument of (>>=) see the password. Something like this:...

data Classification pw a = Classification pw a
declassify (Classification pw a) pw' = case pw' of
                                         pw -> Just a
                                         _  -> Nothing

type Secret = Classification "xyzzy"

...but that doesn't parse.

Is it even possible to have a type like this that still observes the monad rules? Is this the sort of thing that I need to understand arrows to pull off?
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to