Где находится parseRoutesNoCheck в Yesod

#haskell #yesod

#haskell #yesod

Вопрос:

Я начал изучать язык Haskell и веб-фреймворк Yesod. Однако, когда я попытался использовать «parseRoutesNoCheck» для mkYesod, компилятор не смог сопоставить возвращаемый тип (ресурс) 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
  

Я использую компилятор Glasgow Haskell версии 7.0.3 и yesod-core-0.9.2.

Ответ №1:

Вы должны просто использовать 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 (и всего остального, если на то пошло). Фрагменты кода часто встречаются в книге Yesod или в репозиториях github, можно узнать из этих источников.


Редактировать: мне не хватает полного ответа. По-видимому, в настоящее время семейство parseRoutes and находится в «Yesod.Отправка», которая только повторно экспортируется из скрытого модуля Yesod.Внутренний.Анализ маршрутов. parseRoutesNoCheck определяется в Yesod.Internal.RouteParsing , но никогда не раскрывается, поскольку вы, вероятно, всегда хотите проверять неперекрывающиеся маршруты.

Я надеюсь, что это прояснит немного больше.

Комментарии:

1. Спасибо за ответ. Я следую примеру из книги Yesod (что действительно здорово). Итак, я знаю, что parseRoutes отлично работает для кода. Но я пытаюсь использовать parseRoutesNoCheck, потому что я хочу определить Yesod как: mkYesod "Test" [parseRoutes| /page/#String PageR GET /#String UserR GET |] и Yesod. В Dispatch нет parseRoutesNoCheck. Prelude Main Yesod.Dispatch> :type parseRoutesNoCheck <interactive>:1:1: Not in scope: parseRoutesNoCheck»

2. Итак, если parseRoutesNoCheck больше не доступен, я изменяю определение Yesod так, чтобы в нем были только неперекрывающиеся маршруты.