
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
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
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
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
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