Haskell on a Horse ================== Haskell on a Horse (HoH) is a combinatorial web framework for the programming language Haskell. It is currently at an early, unsettled stage of development. It is available under the "BSD3" open-source license. Installing and Using HoH ------------------------ cabal install on-a-horse > {-#LANGUAGE Arrows, QuasiQuotes, ScopedTypeVariables #-} > import Web.Horse > import Control.Applicative > import Control.Arrow > import Control.Monad > import Control.Monad.Cont > import Data.Maybe > import Data.Monoid > import Data.List.Split (splitOn) > import Control.Arrow.Transformer.All > import Text.Pandoc Atomic Components ------------------- An HoH application is built up from atomic components. A component is a complete HoH application all by itself: it can render itself, and respond to input.
> > ex1 = proc url -> do > (fo,num::Maybe Integer) <- readForm "enter a number" -< () > returnA -< wrapForm fo > | EXAMPLE |
> ex2 :: HoH Url (Html ()) > ex2 = proc url -> do > (fo1, oper) <- enumForm "operation" > [("times", (*)), > ("plus", (+))] -< () > (fo2, x::Maybe Integer) <- readForm "x" -< () > (fo3, y::Maybe Integer) <- readForm "y" -< () > let result = show <$> (oper <*> x <*> y) > runHamlet -< [$hamlet| > %form!method=POST!action="" > Calculate a number! > %br > $fo1$ $fo2$ $fo3$ > Result: > $maybe result res > $res$ > %br > %input!type=submit |] | EXAMPLE |
> ex3 :: HoH Url (Html ()) > ex3 = formSum "example to run" [("example 1",ex1),("example 2",ex2)] mempty > >>> arr wrapForm | EXAMPLE |
> ex4 = proc url -> do > (fo,result) <- term "expression" -< () > runHamlet -< [$hamlet| > %form!method=POST!action="" > $fo$ > Result: > $maybe result res > $show res$ > %input!type=submit > %br |] > where > term :: String -> HoH () (FormOut, Maybe Integer) > term label = catchAuto $ formSum label > [("number", number label), > ("add",oper label "add" (+)), > ("multiply",oper label "multiply" (*))] (mempty, Nothing) > > number :: String -> WithError (HoH () (FormOut, Maybe Integer)) > () (FormOut, Maybe Integer) > number termLabel = proc () -> do > fo1 <- linkForm "cancel" (term termLabel) -< () > (fo2,x) <- readForm "number" -< () > returnA -< (fo1 `mappend` fo2, x) > > oper termLabel label f = proc () -> do > (fo1) <- linkForm "cancel" (term termLabel) -< () > (fo2,x) <- liftError (term "x") -< () > (fo3,y) <- liftError (term "y") -< () > out <- runHamlet -< [$hamlet| > %div.oper > $fo1$ > $label$ > %br > $fo2$ $fo3$ |] > returnA -< (out, f <$> x <*> y) | EXAMPLE |
> ex5 = proc url -> do > (dispatch $ staticUrls fourOhFour $ > [("", urls), > ("ex1", ex1), > ("ex2", ex2), > ("ex3", ex3), > ("ex4", ex4)]) -< (url,url) | EXAMPLE |