Пустой блок do yesod после создания нового обработчика

Aug 21 2020

Я пытаюсь создать новый маршрут в yesod / haskell с обработчиком state, но получаю сообщение об ошибке empty 'do' block

Действия по воспроизведению следующие:

  1. Создайте новое приложение yesod: stack new haskellYesod yesodweb/simple
  2. yesod add-handler для добавления нового обработчика с параметрами:
    • Название маршрута: Штат
    • Шаблон маршрута: / состояние /
    • Методы: 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 $ thiswontworkи генерирует Empty 'do' blockсообщение.

Чтобы решить проблему, достаточно добавить {-# LANGUAGE TemplateHaskell #-}его в начало State.hsфайла.

Sandro_V Aug 20 2020 at 23:32

Проблема заключалась в отсутствии расширений. После добавления следующего ошибка исчезла:

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