2011-10-02 36 views
1

我開始學習Haskell語言和Yesod web框架。 但是,當我嘗試對mkYesod使用「parseRoutesNoCheck」時,編譯器無法匹配parseRoutesNoCheck的返回類型(Resource)。Yesod的parseRoutesNoCheck在哪裏

$ ghc simple_yesod.hs 
[1 of 1] Compiling Main    (simple_yesod.hs, simple_yesod.o) 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Loading package ffi-1.0 ... linking ... done. 
Loading package bytestring-0.9.1.10 ... linking ... done. 
Loading package array-0.3.0.2 ... linking ... done. 
Loading package containers-0.4.0.0 ... linking ... done. 
Loading package deepseq-1.1.0.2 ... linking ... done. 
Loading package text-0.11.0.6 ... linking ... done. 
Loading package path-pieces-0.0.0 ... linking ... done. 
Loading package pretty-1.0.1.2 ... linking ... done. 
Loading package template-haskell ... linking ... done. 
Loading package web-routes-quasi-0.7.1 ... linking ... done. 

simple_yesod.hs:9:36: 
    Couldn't match expected type `yesod-core-0.9.2:Yesod.Internal.RouteParsing.Resource' 
       with actual type `Resource' 
    In the return type of a call of `Resource' 
    In the expression: 
     Resource "PageR" [StaticPiece "page", SinglePiece "String"] ["GET"] 
    In the second argument of `mkYesod', namely 
     `[Resource 
      "PageR" [StaticPiece "page", SinglePiece "String"] ["GET"], 
     Resource 
      "UserR" [StaticPiece "user", SinglePiece "String"] ["GET"]]' 

看來我使用了錯誤的parseRoutesNoCheck,但哪裏是正確的Module?

simple_yesod.hs如下。

{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-} 
import Yesod 
import Web.Routes.Quasi.Parse 
import qualified Text.Blaze.Html5 as H 

data Test = Test { 
    } 

mkYesod "Test" [parseRoutesNoCheck| 
/page/#String  PageR GET 
/user/#String  UserR GET 
|] 

instance Yesod Test where 
    approot _ = "" 
    defaultLayout widget = do 
         content <- widgetToPageContent widget 
         hamletToRepHtml [hamlet| 
\<!DOCTYPE html> 

<html> 
    <head> 
    <title>#{pageTitle content} 
    <body> 
    <ul id="navbar"> 
    <div id="content"> 
     \^{pageBody content} 
|] 


getUserR :: String -> Handler RepHtml 
getUserR userName = defaultLayout 
        (do 
         setTitle $ H.toHtml $ "Hello " ++ userName 
         addHamlet $ html userName 
        ) 
    where 
     html page = [hamlet| 
<h1>User: #{userName} 
<p>This page is for user: #{userName} 
|] 

getPageR :: String -> Handler RepHtml 
getPageR pageName = defaultLayout 
        (do 
         setTitle $ H.toHtml $ "Article: " ++ pageName 
         addHamlet $ html pageName 
        ) 
    where 
     html page = [hamlet| 
<h1>Page: #{pageName} 
<p>This page is for page: #{pageName} 
|] 

main :: IO() 
main = do 
    warpDebug 3000 $ Test 

我正在使用格拉斯哥Haskell編譯器,版本7.0.3和yesod-core-0.9.2。

回答

2

您應該簡單地使用parseRoutes而不是parseRoutesNoCheck。您還可能想要添加module Main where並刪除import Web.Routes.Quasi.Parse,因爲Yesod模塊已導出parseRoutes

下面是我提到的修改的完整代碼。

{-# LANGUAGE TypeFamilies, QuasiQuotes, TemplateHaskell, MultiParamTypeClasses, OverloadedStrings #-} 
module Main where 
import Yesod 
import qualified Text.Blaze.Html5 as H 


data Test = Test { 
    } 

mkYesod "Test" [parseRoutes| 
/page/#String  PageR GET 
/user/#String  UserR GET 
|] 

instance Yesod Test where 
    approot _ = "" 
    defaultLayout widget = do 
         content <- widgetToPageContent widget 
         hamletToRepHtml [hamlet| 
\<!DOCTYPE html> 

<html> 
    <head> 
    <title>#{pageTitle content} 
    <body> 
    <ul id="navbar"> 
    <div id="content"> 
     \^{pageBody content} 
|] 


getUserR :: String -> Handler RepHtml 
getUserR userName = defaultLayout 
        (do 
         setTitle $ H.toHtml $ "Hello " ++ userName 
         addHamlet $ html userName 
        ) 
    where 
     html page = [hamlet| 
<h1>User: #{userName} 
<p>This page is for user: #{userName} 
|] 

getPageR :: String -> Handler RepHtml 
getPageR pageName = defaultLayout 
        (do 
         setTitle $ H.toHtml $ "Article: " ++ pageName 
         addHamlet $ html pageName 
        ) 
    where 
     html page = [hamlet| 
<h1>Page: #{pageName} 

一個好主意是嘗試,當你在耶索德(和其他一切爲此事)的學習階段是複製現有的例子。代碼片段通常出現在Yesod書籍或github回購站中,可以從這些來源中學習。


編輯:我缺乏完整的答案。當前顯然parseRoutes和家庭位於"Yesod.Dispatch"只是從隱藏模塊Yesod.Internal.RouteParsing重新導出。 parseRoutesNoCheckYesod.Internal.RouteParsing中定義,但從未公開,因爲您可能總是希望檢查不重疊的路線。

我希望這個更清楚一點。

+0

謝謝你的回答。我遵循Yesod書中的例子(這真的很棒)。所以我知道parseRoutes對代碼工作正常。但我試圖使用parseRoutesNoCheck,因爲我想將Yesod定義爲: 'mkYesod「Test」[parseRoutes | /page /#String PageR GET /#String UserR GET |]' 和Yesod.Dispatch沒有parseRoutesNoCheck。 'Prelude Main Yesod.Dispatch>:type parseRoutesNoCheck :1:1:not in scope:'parseRoutesNoCheck'' – gonbe

+0

因此,如果parseRoutesNoCheck不再可用,我更改Yesod定義以便它只有不重疊的路線。 – gonbe