
On Monday 09 August 2010 21:19:01, John Lato wrote:
I don't find purify2 particularly helpful because I almost never want to break out of any arbitrary monad; I want to be able to break out of a specific monad without knowing which monad it is, that is:
purify3 :: Monad m => m a -> a purify3 = undefined --the only possible definition...
Just to be obnoxious: purify3 = const undefined ;)
However, I just realized that something else is almost as good:
evalCont :: Cont r a -> r evalCont k = runCont k id
Wouldn't you want the signature Cont r a -> a to break out? Also: ContBreak.hs:6:23: Couldn't match expected type `r' against inferred type `a' `r' is a rigid type variable bound by the type signature for `evalCont' at ContBreak.hs:5:17 `a' is a rigid type variable bound by the type signature for `evalCont' at ContBreak.hs:5:19 In the second argument of `runCont', namely `id' In the expression: runCont k id In the definition of `evalCont': evalCont k = runCont k id evalCont :: (forall r. Cont r a) -> a evalCont k = runCont k id would work (but is something different).
As Cont is the "Mother of all monads", it can be used to emulate the behavior of any other monad. If you had a library with instances of MonadReader, MonadWriter, MonadState, etc. (or operational equivalents) defined for the Cont monad, then you would have a purify function that works for all interesting monads (except IO, STM, and maybe ST), which is almost as good.
John