On 09/10/06, Seth Gordon <[EMAIL PROTECTED]> wrote:
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?

Why not just:

secret :: a -> Classification String a
secret = Classification "xyzzy"

The password string isn't part of the type, it doesn't even
necessarily exist at compile time. You might have just got confused
between type and data constructors for a moment.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to