簡體   English   中英

forM_塊內部出現Blaze-html類型錯誤

[英]Blaze-html type error inside forM_ block

我剛剛開始使用Spock,persistent和blaze-html進行Haskell Web開發。

在我擁有的其中一條路線中,我想加載所選表格中的每一行。 我做這樣的事情:

  get ("/show/flight/" <//> (var :: Var Integer)) $ \f -> requireUser $ \(_, l) -> do
     fs <- runSQL $ loadFlightInfos f

     case fs of
        [] -> blaze $ template False (showResultAlertBar False "Oops, something went wrong! Please try again.")
        _  -> blaze $ template True (H.toHtml $ usersUsername l) loadFlightSeat

           where
              loadFlightSeat :: H.Html
              loadFlightSeat =
                 forM_ fs $ \fs' -> do
                    sid <- runSQL $ getSeatIdByFlight fs' c

                    case sid of
                       Nothing  -> H.div H.! A.class_ "alert alert-danger" $ "Oops, something went wrong! Please try again."
                       Just rid -> H.a H.! A.href (H.toValue $ "/flight/seat/" <> show c <> "/" <> show (fromIntegral $ (fromSqlKey . entityKey) sid)) H.! A.class_ "btn btn-theme" $ H.toHtml fs'

loadFlightInfos具有類型:

Integer -> SqlPersistM [Entity Flight]

和getSeatIdByFlight:

T.Text -> Integer -> SqlPersistM (Maybe (Entity Flight))

我從Spock的博客示例應用程序復制了runSQL ,它是這樣的:

runSQL :: (HasSpock m, SpockConn m ~ SqlBackend) => SqlPersistT (NoLoggingT (ResourceT IO)) a -> m a
runSQL action = runQuery $ \conn -> runResourceT $ runNoLoggingT $ runSqlConn action conn

我得到的類型錯誤:

Couldn't match expected type ‘SqlBackend’
        with actual type ‘SpockConn Text.Blaze.Internal.MarkupM’
In the expression: runSQL
In a stmt of a 'do' block:
   sid <- runSQL $ getSeatIdByFlight fs' c

我仍然不理解這種類型錯誤,因為我知道runSQL是從持久性到Spock的包裝,並且如果我只是想輸出HTML,為什么它不能通過類型檢查?

如何解決此類型錯誤?

免責聲明:我沒有運行您的代碼。

我知道runSQL是從持久性到Spock的包裝

沒錯,這就是您的問題所在。 runSQL的類型是:

runSQL :: (HasSpock m, SpockConn m ~ SqlBackend)
       => SqlPersistT (NoLoggingT (ResourceT IO)) a -> m a

結果類型(HasSpock m, SpockConn m ~ SqlBackend) => ma告訴我們, runSQL在Spock monad中給出結果。 因此, loadFlightSeat應該是Spock monad計算。 但是,您給它H.Html類型,它與Spock monad沒有關系。 這個問題可能會自動消失,如果你刪除的錯誤的類型簽名loadFlightSeat和調整的用法loadFlightSeat因此:

     flightSeat <- loadFlightSeat -- Returns an H.Html value in the Spock monad.
     case fs of
        [] -> blaze $ template False (showResultAlertBar False "Oops, something went wrong! Please try again.")
        _  -> blaze $ template True (H.toHtml $ usersUsername l) flightSeat

PS:您遇到的類型錯誤...

Couldn't match expected type ‘SqlBackend’
        with actual type ‘SpockConn Text.Blaze.Internal.MarkupM’
In the expression: runSQL
In a stmt of a 'do' block:
   sid <- runSQL $ getSeatIdByFlight fs' c

...非常奇怪,因為H.Html 恰好是MarkupM ()的同義詞 ,而MarkupM是由blaze定義的monad。 結果,給您的loadFlightSeat簽名使編譯器嘗試將Spock的monad與MarkupM匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM