1

Haskell言語とYesodウェブフレームワークを学び始めました。しかし、mkYesodに「parseRoutesNoCheck」を使用しようとすると、コンパイラーが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を使用しているようですが、正しいモジュールはどこにありますか?

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

GlasgowHaskellコンパイラバージョン7.0.3とyesod-core-0.9.2を使用しています。

4

1 に答える 1

2

parseRoutesではなく、単に使用する必要がありparseRoutesNoCheckます。また、モジュールはすでにエクスポートしているため、追加しmodule Main whereて削除することもできます。import Web.Routes.Quasi.ParseYesodparseRoutes

これが、私が言及した変更を加えた完全なコードです。

{-# 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 (およびその他すべて) の学習段階にあるときに、既存の例をコピーすることをお勧めします。コード スニペットは、Yesod ブックや github リポジトリでよく見られます。これらのソースから学ぶことができます。


編集:完全な答えがありません。最近ではparseRoutesand ファミリーは"Yesod.Dispatch"にあり、隠しモジュールYesod.Internal.RouteParsingからのみ再エクスポートされます。parseRoutesNoCheckで定義されてYesod.Internal.RouteParsingいますが、公開されることはありません。これは、重複しないルートを常にチェックする必要があるためです。

これでもう少し明確になることを願っています。

于 2011-10-02T08:05:38.770 に答える