
apfelmus wrote:
Felipe Lessa wrote:
casePromptOf :: (r -> b) -> (forall a. p a -> (a -> b) -> b) -> Prompt p r -> b casePromptOf done cont (PromptDone r) = done r casePromptOf done cont (Prompt p c ) = cont p (casePromptOf done cont . c)
[is just as general as]
casePromptOf' :: (r -> f c) -> (forall a,b. p a -> (a -> f b) -> f b) -> Prompt p r -> f c
That's nice. So let's implement Prompt differently, using casePromptOf as a template:
newtype Prompt p r = Prompt { runP :: forall b . (r -> b) -> (forall a . p a -> (a -> b) -> b) -> b }
We can define a Monad instance easily enough:
instance Monad (Prompt p) where return a = Prompt $ \done _ -> done a f >>= g = Prompt $ \done prm -> runP f (\x -> runP (g x) done prm) prm
prompt can be implemented as follows:
instance MonadPrompt (Prompt p) where prompt p = \done prm -> prm p done
And finally define some handy functions for running it,
runPromptC :: (r -> b) -> (forall a . p a -> (a -> b) -> b) -> Prompt p r -> b runPromptC ret prm p = runP p ret prm
(runPromptC is just a different name for casePromptOf)
runPromptM :: Monad m => (forall a . p a -> m a) -> Prompt p r -> m r runPromptM prm = runPromptC return (\p cont -> prm p >>= cont)
The interesting point here is that by working with continuations, we could eliminate the recursive call of (>>=) in its own implementation, curing the quadratic slowdown for left associative uses of (>>=). enjoy, Bertram P.S. I've written a small peg solitaire game using Prompt and gtk2hs, available from http://int-e.home.tlink.de/haskell/solitaire.tar.gz Maybe it's interesting to somebody.