User:Benmachine/Cont
From HaskellWiki
(Difference between revisions)
(→Acknowledgements) |
|||
| Line 139: | Line 139: | ||
* [http://blog.sigfpe.com/2008/12/mother-of-all-monads.html The Mother of all Monads] | * [http://blog.sigfpe.com/2008/12/mother-of-all-monads.html The Mother of all Monads] | ||
which is more-or-less the above trick but in a bit more detail. | which is more-or-less the above trick but in a bit more detail. | ||
| + | |||
| + | === Disclaimer === | ||
| + | |||
| + | I'm currently unsure if I've fallen victim to Brent's (in)famous [http://byorgey.wordpress.com/2009/01/12/abstraction-intuition-and-the-monad-tutorial-fallacy/ monad tutorial fallacy]. I know that there was more in my learning process than I've been able to reproduce above, but I do think I'm doing this in a genuinely new style – <hask>Cont</hask> always seems to be presented in such vague terms, and people don't provide actual examples of the way it works. | ||
| + | |||
| + | === A moderately heretical conclusion === | ||
| + | |||
| + | Sometimes looking at types isn't the best way to understand things! I've implemented the <hask>Cont</hask> type class instances before, and the types ensure that you pretty much help but do it the right way. But that doesn't tell you what you're doing, or why you did it that way. I never understood <hask>Cont</hask> until I came across the natural interpretation of its content. It's a bit like fitting the pieces of a puzzle together without looking at the picture. | ||
Revision as of 00:22, 20 January 2012
Contents |
1 A practical Cont tutorial
It seems to me likeCont
ContT
contstuff :: Magic a contstuff = do thing1 thing2 -- Now I want to manipulate the rest of the computation. -- So I want a magic function that will give me the future to -- play with. magic $ \rest -> -- 'rest' is the rest of the computation. Now I can just do it, -- or do it twice and combine the results, or discard it entirely, -- or do it and then use the result to do it again... it's easy to -- imagine why this might be useful. messAboutWith rest thing3 -- these might get done once, several times, thing4 -- or not at all.
magic
r
magic
r
r
magic
x <- magic $ \rest -> -- ... thingInvolving x
x
magic
a -> r
r
(a -> r) -> r
magic :: (a -> r) -> r -> Magic a
Magic a = Cont r a magic = Cont
Tada!
The thing withCont
Functor
instance Functor (Cont r) where fmap f (Cont g) = -- ...
Cont
fmap f (Cont g) = Cont $ \rest -> -- ...
g
\rest -> stuffWith (rest val)
val
<-
rest
f
fmap f (Cont x) = Cont $ \rest -> x (\val -> rest (f val))
Applicative
instance Applicative (Cont r) where pure x = Cont $ \rest -> -- ...
We don't want to do anything special here. The rest of the computation wants a value, let's just give it one:
pure x = Cont $ \rest -> rest x
<*>
Cont f <*> Cont x = Cont $ \rest -> -- ...
fmap
Cont f <*> Cont x = Cont $ \rest -> f (\fn -> x (\val -> rest (fn val)))
Monad
runCont
case
let
1.1 So what's callCC?
"Call with current continuation". I don't really get the name. Basically, you usecallCC
ret <- callCC $ \exit -> do -- A mini Cont block. -- You can bind things to ret in one of two ways: either return -- something at the end as usual, or call exit with something of -- the appropriate type, and the rest of the block will be ignored. when (n < 10) $ exit "small!" when (n > 100) $ exit "big!" return "somewhere in between!"
exit
runCont
1.2 What about ContT?
The thing to understand withContT
newtype ContT r m a = ContT (Cont (m r) a) deriving (Functor, Applicative, Monad) runContT :: ContT r m a -> (a -> m r) -> m r runContT (ContT m) = runCont m
MonadTrans
1.3 Some real examples
The examples in the mtl doc are unconvincing. They don't do anything genuinely daring. Some of them work in any monad! Here's a more complex example:
-- This tends to be useful. runC :: Cont a a -> a runC c = runCont c id faff :: Integer -> Maybe Integer faff n = runC $ do test <- Cont $ \try -> case try n of Nothing -> try (2*n) res -> fmap (subtract 10) res return $ if test < 10 then Nothing else Just test
return
test = n
(2*n)
Nothing
Just 12
Just 0
1.4 Acknowledgements
I think it was the legendary sigfpe who made this click for me, after thinking about how this works:
and there's also this:
which is more-or-less the above trick but in a bit more detail.
1.5 Disclaimer
I'm currently unsure if I've fallen victim to Brent's (in)famous monad tutorial fallacy. I know that there was more in my learning process than I've been able to reproduce above, but I do think I'm doing this in a genuinely new style –Cont
1.6 A moderately heretical conclusion
Sometimes looking at types isn't the best way to understand things! I've implemented theCont
Cont
