Haskell Happstack 和 blaze 的网络路由示例未显示两个不同的 URL

Haskell web routes example with Happstack and blaze is not showing two different URLs

我已经完成了 Happstack 速成课程并且有工作改革和网络路由示例。我试图像这样将两者结合起来,但是 showURL Home 和 showURL Login 对我的示例应用程序显示相同的 URL。

这是示例应用程序

           , GeneralizedNewtypeDeriving
           , TemplateHaskell
           , TypeOperators
           , GADTs
           , OverloadedStrings
           , TypeFamilies
#-}
module Main where

import Data.Data
import Control.Applicative
import Control.Monad
import Control.Monad.Trans.Class
import           Text.Blaze
import           Text.Blaze.Html
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as A
import Text.Reform
import Text.Reform.Happstack
import Text.Reform.Blaze.Text
import Happstack.Server
import Web.Routes 
import Web.Routes.TH
import Web.Routes.Happstack
import Web.Routes.Boomerang
import Text.Boomerang.TH
import Text.Boomerang.HStack
import Text.Boomerang.Texts ()
import Data.Text

data Sitemap
    = Login
    | Home
      deriving (Eq, Ord, Read, Show, Data, Typeable)


-- $(derivePathInfo ''Sitemap)
$(makeBoomerangs ''Sitemap)

sitemap :: Router () (Sitemap :- ())
sitemap =  rLogin
        <> rHome



site :: Site Sitemap (ServerPartT IO Response)
site =
    setDefault Login $ boomerangSiteRouteT route sitemap


route :: Sitemap -> RouteT Sitemap (ServerPartT IO) Response
route Login = loginPage
route Home  = homePage

appTemplate :: String
            ->  [H.Html]
            -> H.Html
            -> H.Html
appTemplate title headers body =
  H.html $ do
    H.head $ do
      H.title $ toHtml title
      sequence_ headers
    H.body $ do
      body

data LoginData = LoginData 
  { username :: Text
  , password :: Text
  }


renderLoginData :: LoginData -> H.Html
renderLoginData loginData = H.dl $ do H.dt $ "name: "
                                      H.dd $ (text . username) loginData
                                      H.dt $ "password: "
                                      H.dd $ (text . password) loginData

data AppError
  = AppCFE (CommonFormError [Input])
  deriving Show

instance FormError AppError where
  type ErrorInputType AppError = [Input]
  commonFormError = AppCFE

loginForm :: Form (ServerPartT IO) [Input] AppError Html () LoginData
loginForm = LoginData 
              <$>  label (Data.Text.pack "username:") ++> inputText (Data.Text.pack "") <++ br
              <*>  label (Data.Text.pack "password: ") ++> inputPassword <++ br
              <*  inputSubmit "post"
 

homePage :: RouteT Sitemap (ServerPartT IO) Response
homePage =  ok $ toResponse $
    H.html $ do
      H.body $ do
        H.p "You have logged in successfully"

loginPage :: RouteT Sitemap (ServerPartT IO) Response
loginPage = 
  do homeURL <- showURL Home
     loginURL <- showURL Login
     -- formHTML <- lift $ reform (form homeURL) "loginPage" displayMessage Nothing loginForm 
     ok $ toResponse $
       H.html $ do
         H.head $ do
           H.title "Hello Form"
         H.body $ do
           -- formHTML
           H.span $ toHtml homeURL
           H.br
           H.span $ toHtml loginURL 
  where
    displayMessage :: LoginData -> ServerPartT IO H.Html
    displayMessage loginData = return $ appTemplate "Form validation result" [] $ renderLoginData loginData 


main :: IO ()
main = simpleHTTP nullConf $
         msum [ implSite "http://localhost:8000" "" site
                
              ]

loginPage中的homeURL和loginURL是等价的,应该有各自的路径。当我参加 Happstack 速成课程并参考它时,Sitemap 的 Home 和 UserOverview 构造函数收到它们自己的 URLs,所以我不确定为什么我的示例脚本的 Sitemap 的构造函数 Login 和 Home 没有收到不同的 URLs.

我发现这是导入中的一个微妙问题。我需要包括这些导入/

import Prelude隐藏(head, id, (.)) 导入 Control.Category (id, (.))

我需要确定 Prelude 的组合 (.) 运算符和 Control.Category 的组合 (.) 运算符之间的区别。

添加导入后,我可以将站点地图更改为

sitemap :: Router () (Sitemap :- ())
sitemap =  rLogin
        <> lit (Data.Text.pack "home") .rHome

在使用 Prelude 的合成运算符时出现问题之前。