Hi Haskellers. In my package MFlow [1] I program an entire web navigation in a single procedure. That happened in the good-old WASH web application framework. The problem is the back button in the Browser. To go back in the code to the previous interactions when the data input does not match the expected because the user pressed the back button one or more times, i came across this Monad specimen,: that solves the problem. data FailBack a = BackPoint a -- will go back to this point | NoBack a . -- Normal outcome | GoBack -- "exception":: must go to the last backPoint newtype BackT m a = BackT { runBackT :: m (FailBack a ) } -- this monad nas a loop instance Monad m => Monad (BackT m) where fail _ = BackT $ return GoBack return x = BackT . return $ NoBack x x >>= f = BackT $ loop where loop = do v <- runBackT x case v of NoBack y -> runBackT (f y) -- business as usual BackPoint y -> do z <- runBackT (f y) case z of GoBack -> loop -- if x was a backpoint, then redirects the flow to this backpoint other -> return other GoBack -> return GoBack --propagate the signal back This monad does not perform exploration of alternatives as is the case of MonadPlus instances. It does not perform the kind of backtracking of "nondeterministic" three navigations in the Prolog style. It just go back to the last point where the computation can restart again in a sequence of actions. In this example: liftBackPoint f= BackT $ f >>= \x -> return $ BackPoint x test= runBackT $ do lift $ print "will not return back here" liftBackPoint $ print "will return here" n2 <- lift $ getLine lift $ print "second input" n3 <- lift $ getLine if n3 == "back" then fail "" else lift $ print $ n2++n3 Whenever the second input is "back" The procedure will go back to where liftBackPoint is. Otherwise, it will return the concatenation of the two inputs. If the underlying monad is an instance of MonadState, it can transport the state that caused the failure to the backpoint. Are there something similar? May it be functionally equivalent to something simpler or with more grounds? I looked at some exception monads out there, but they did not seems to share the same idea [1] http://haskell-web.blogspot.com.es/2012/02/web-application-server-with-state...
Sorry, the text example again without HTML formatting: test= runBackT $ do lift $ print "will not return back here" liftBackPoint $ print "will return here" n2 <- lift $ getLine lift $ print "second input" n3 <- lift $ getLine if n3 == "back" then fail "" else lift $ print $ n2++n3 I wrote a blog entry about this : http://haskell-web.blogspot.com.es/2012/03/failback-monad.html 2012/3/28 Alberto G. Corona <agocorona@gmail.com>:
Hi Haskellers.
In my package MFlow [1] I program an entire web navigation in a single procedure. That happened in the good-old WASH web application framework. The problem is the back button in the Browser. To go back in the code to the previous interactions when the data input does not match the expected because the user pressed the back button one or more times, i came across this Monad specimen,: that solves the problem.
data FailBack a = BackPoint a -- will go back to this point | NoBack a . -- Normal outcome | GoBack -- "exception":: must go to the last backPoint
newtype BackT m a = BackT { runBackT :: m (FailBack a ) }
-- this monad nas a loop
instance Monad m => Monad (BackT m) where fail _ = BackT $ return GoBack return x = BackT . return $ NoBack x x >>= f = BackT $ loop where loop = do v <- runBackT x case v of NoBack y -> runBackT (f y) -- business as usual BackPoint y -> do z <- runBackT (f y) case z of GoBack -> loop -- if x was a backpoint, then redirects the flow to this backpoint other -> return other GoBack -> return GoBack --propagate the signal back
This monad does not perform exploration of alternatives as is the case of MonadPlus instances. It does not perform the kind of backtracking of "nondeterministic" three navigations in the Prolog style. It just go back to the last point where the computation can restart again in a sequence of actions.
In this example:
liftBackPoint f= BackT $ f >>= \x -> return $ BackPoint x
test= runBackT $ do lift $ print "will not return back here" liftBackPoint $ print "will return here" n2 <- lift $ getLine lift $ print "second input" n3 <- lift $ getLine if n3 == "back" then fail "" else lift $ print $ n2++n3
Whenever the second input is "back" The procedure will go back to where liftBackPoint is. Otherwise, it will return the concatenation of the two inputs. If the underlying monad is an instance of MonadState, it can transport the state that caused the failure to the backpoint.
Are there something similar? May it be functionally equivalent to something simpler or with more grounds? I looked at some exception monads out there, but they did not seems to share the same idea
[1] http://haskell-web.blogspot.com.es/2012/02/web-application-server-with-state...
Maybe this is a version of William Harrison's DebugT monad with rollback, listed in his periodic table of effects? http://www.cs.missouri.edu/~harrisonwl/Presentations/UIUCFM05.ppt I've never seen a definition of the monad itself... http://www.haskell.org/pipermail/beginners/2010-January/003371.html
Hi Stephen: It could be: It performs a rollback indeed. I guess that this monad can be used in something similar to nonblocking (multilevel) transactions. if "GoBack" is changed to "Goback String", and a trace string is added to each NoBack step, then each NoBack step could sum the traces of all the previous steps. The when GoBack condition is reached, it can transport back the entire trace of the failed execution. to the BackPoint 2012/3/28 Stephen Tetley <stephen.tetley@gmail.com>:
Maybe this is a version of William Harrison's DebugT monad with rollback, listed in his periodic table of effects?
http://www.cs.missouri.edu/~harrisonwl/Presentations/UIUCFM05.ppt
I've never seen a definition of the monad itself... http://www.haskell.org/pipermail/beginners/2010-January/003371.html
There is also recent work by Aaron Turon and Olin Shivers - Modular Rollback through Control Logging http://www.ccs.neu.edu/home/shivers/ http://www.ccs.neu.edu/home/turon/ Note that as well as the paper on Olin Shivers's site there is a more recent monadic presentation on Aaron Turon's site with Conor McBride... On 28 March 2012 18:11, Stephen Tetley <stephen.tetley@gmail.com> wrote:
Maybe this is a version of William Harrison's DebugT monad with rollback, listed in his periodic table of effects?
http://www.cs.missouri.edu/~harrisonwl/Presentations/UIUCFM05.ppt
I've never seen a definition of the monad itself... http://www.haskell.org/pipermail/beginners/2010-January/003371.html
On Wed, Mar 28, 2012 at 01:34:29AM +0100, Alberto G. Corona wrote:
In my package MFlow [1] I program an entire web navigation in a single procedure. That happened in the good-old WASH web application framework. The problem is the back button in the Browser. To go back in the code to the previous interactions when the data input does not match the expected because the user pressed the back button one or more times, i came across this Monad specimen,: that solves the problem.
This definition does not satisfy the right identity law (m >>= return = m) included in the monad definition: *FailBack> BackT [BackPoint 1] >>= return BackT [NoBack 1]
But, on my side, BackT [BackPoint 1] and BackT [NoBack 1] can be made indistinguishable outside the code where the monad is defined. Probably the effect required is not possible without breaking the law 2012/3/31 Ross Paterson <ross@soi.city.ac.uk>:
On Wed, Mar 28, 2012 at 01:34:29AM +0100, Alberto G. Corona wrote:
In my package MFlow [1] I program an entire web navigation in a single procedure. That happened in the good-old WASH web application framework. The problem is the back button in the Browser. To go back in the code to the previous interactions when the data input does not match the expected because the user pressed the back button one or more times, i came across this Monad specimen,: that solves the problem.
This definition does not satisfy the right identity law (m >>= return = m) included in the monad definition:
*FailBack> BackT [BackPoint 1] >>= return BackT [NoBack 1]
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
participants (3)
-
Alberto G. Corona -
Ross Paterson -
Stephen Tetley