Thursday, July 11, 2013

The Web Navigation Monad

The MFlow app server can express routes within normal Haskell monadic code. The FlowM monad backtrack and goes forward to track the URL of any page within the monadic flow.

To make a web application program more close to a plain console application, I created runNavigation, that get the port from the first execution parameter. If not, it read it from the PORT environment variable. If it does not exist, it uses the por 80.

runNavigation executes a persistent navigation (whose state is logged and later recovered when the process has a timeout).  If the flow is not persistent, it must be prefixed with transientNav.

The result is a more close visualization of what the FlowM monad is: a navigation monad.

This example has two routes (letters and numbers). Each one has a simple sucession of pages. The user can navigate forward and backward, introduce any url and the program will track the proper page to respond.

I installed it on Heroku:

http://mflowdemo.herokuapp.com/noscript/restnav

This page for example, points to the second page of the numbers:

http://mflowdemo.herokuapp.com/noscript/restnav/1/2

Notice the restful URLs generated, that can be entered in the address box at any time.

When the flow finish, it goes to the beginning again.

From numbers it is possible to have a link to any letter by means of a HTML link, instead of a wlink. (wlinks return results to the flow where they are in)


main= runNavigation "" $ transientNav $ do

  liftIO $ print "start/restart"

  setHeader $ html . body

  option <- ask  $   wlink "a"  << p << "letters"
                 <|> wlink "1" << p << "numbers"

  case option of
    "1" -> do
          page $ wlink "2" << pagefor "1"
          page $ wlink "3" << pagefor "2"
          page $ wlink "4" << pagefor "3"
          page $ wlink ()  <<  "menu"
    "a" -> do
          page $ wlink "b" << pagefor "a"
          page $ wlink "c" << pagefor "b"
          page $ wlink "d" << pagefor "c"
          page $ wlink ()  <<  "menu"

pagefor x= p << "page for"
        <> b << x
        <> p << "goto next page"



page is a synonym of ask

It is a navigation of 9 pages within the main procedure. The application is stateless, since the GET URLs have ever the same response. There is no state. It is, simply, a navigation.




No comments: