Monad

W a

Monad

Monad

W



> data Threat = LOW | GUARDED | ELEVATED | HIGH | SEVERE

> deriving (Eq,Ord,Enum,Show)



max

LOW

max LOW ELEVATED = ELEVATED



> data T a = T Threat a deriving Show



max

LOW

return

f :: a -> T b

x :: T a

x >>= f

max

x

f



> instance Monad T where

> return x = T LOW x

> (T t x) >>= f = let T t' x' = f x in T (max t t') x'



h





> g x y = y >>= (return . (+x))

> h x y = x >>= (\x -> g x y)





h (T ELEVATED 3) (T GUARDED 6)

g

h

h

Threat

max

++

Writer

Maybe

I've previously introduced the idea of a monad being a kind of one way wrapper. Theinterface allows you to wrap things, but not unwrap them again. And it allows you to apply any function you like to a wrapped object, as long as it stays wrapped. I also indicated how this could be used to model a notion of taint. If you have some data from a tainted source - for example it's unreliable, then the trivial monad can do a nice job of keeping track of all other data that has been tainted by contact with this data. What I also want to show is that a wide variety of other monads can be interpreted in terms of taint. What this means is that despite its simplicity, the trivial monad is always worth keeping in the back of your mind because it is a protoype for many other monads.You could imagine using this taint idea as a security model. Any data of typeis considered secret and a threat to public safety if it is revealed. By sticking to theinterface we force the compiler to make sure that any data depending on secret data is itself marked secret. This makes it easy to keep secret data sequestered - at least as long as people only use theinterface toBut suppose this isn't good enough and we need to track not only which data is secret, but also the threat level to public safety should a secret be revealed. With this in mind, define the Homeland Security Threat Level It's a monoid because it has an associative binary operatorand has an identity. For exampleWe want to tag some of our data with a threat level. In addition, we want to ensure that if we combine two tagged pieces of data, x and y, the combination must be tagged with the worse of the two threat levels. That's why we have the monoid structure that allows us to combine two threats.So defineBut to use this it appears we have to thread use of thefunction all the way through our code. It'll be a nightmare to implement. But there's a solution. What we want is a monad!Considerto be the default threat level of all data and that tells us how to defineNow suppose we have a functionand some data. We want to be able to apply f to x using the monad interface:. The threat level of the result should be theof the two possible sources of threat:itself or the result of computing. With that in mind:Notice how we've now shown how to implement threat combination in a way that can be used by any code that uses the monad interface. So now we can take last week's definition ofand use it:Try evaluating. It just works, even thoughandwere originally written for the trivial monad! So it's trivial to make code that's written monadically work with our new threat level system. This should give some idea of the power of monads. We've completely changed the sematics of our monadic addition operator,, without lifting a finger to edit it.But notice that I didn't need to talk about threats at all. I've shown how to tag data with other data that's implicitly carried along with it. All we needed was a rule for combining pairs of tags. Our tags were of type. Instead we could have used strings and instead ofwe could have used. If we had, then we'd have a way of implicitly carrying around logs with our computations. In fact, all I have done here is implement a special case of the Writer monad. But I still think that thinking in terms of data that is quarantined in some way helps with the intuition.I hope that by starting with the trivial monad last week, and upgrading in a natural way to the Homeland Security Threat Level monad, I've given an easy way to think about monads. Our ordinary intuitions about taint, for example that if a clean object touches a tainted one it becomes tainted itself, carry over to monads. And themonad isn't the only one that can be thought of in these terms. I hope at some point soon to look at theand list monads in this way too.

Labels: haskell, monad