
David Roundy wrote:
Try
module Secret (Secret, classify, declassify) where
data Secret a = Secret String a
classify :: String -> a -> Secret a classify pw x = Secret pw x
declassify :: Secret a -> String -> Maybe a declassify (Secret pw x) pw' | pw' == pw = Just x declassify (Secret _ _) _ = Nothing
instance Monad Secret where return = classify "" (Secret pw x) >>= f = case f x of Secret _ y -> Secret pw y
Now return itself doesn't assign a password, but you can classify something manually, and then perform computations on that data in a safe manner. It's just as safe as your code, because the constructor of secret is hidden which hides the password just as well as the data.
What should 'q >>= r' mean, when 'q' and 'r x' are secrets with different passwords? In the code above, the result is a secret with the same password as 'q'. This allows you to declassify any secret without knowing its password: break :: Secret a -> a break q = fromJust $ declassify (classify "bloep" () >> q) "bloep" . -- Mr. Pelican Shit may be Willy. ^ /e\ ---