新しいハンドラーを作成した後、空のdoブロックyesod

Aug 21 2020

stateというハンドラーを使ってyesod / haskellに新しいルートを作成しようとしましたが、エラーが発生します empty 'do' block

再現する手順は次のとおりです。

  1. 新しいyesodアプリケーションを作成します。 stack new haskellYesod yesodweb/simple
  2. yesod add-handler paramsを使用して新しいハンドラーを追加する場合:
    • ルート名:州
    • ルートパターン:/ state /
    • メソッド:GET
  3. 次のコードを追加します src/Handler/State.hs
module Handler.State where

import Import

getStateR :: Handler Html
getStateR = do
    defaultLayout $ do $(widgetFile "bla")

  1. 簡単なHTMLサイトを作成しますtemplates/bla.hamlet
<h1> BLA!
  1. でサーバーを起動します stack exec yesod devel

その後、エラーが発生します。

src/Handler/State.hs:7:21: error: Empty 'do' block
  |
7 |     defaultLayout $ do

回答

2 K.A.Buhr Aug 23 2020 at 04:39

何が起こっているのかというと、TemplateHaskell拡張子$(...)がないと、構文が意図したとおりに認識されないということです。代わりに、次のように記述した場合$と同様に、do-block、演算子、式の順に解析され(...)ます。

getStateR = do
    defaultLayout $ (do $ widgetFile "bla")
                     ^^ empty do-block

スタンドアロンプ​​ログラムでも同じ問題が発生します。

main = do
    $(thiswontwork)

これもとして解析されmain = do $ thiswontworkEmpty 'do' blockメッセージを生成します。

問題を解決するには{-# LANGUAGE TemplateHaskell #-}State.hsファイルの先頭に追加するだけで十分です。

Sandro_V Aug 20 2020 at 23:32

問題は拡張機能がないことでした。以下を追加した後、エラーは消えました:

{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}