在form_block中出现html类型错误



我刚刚开始使用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是从persistent到Spock的包装器

没错,这就是你的问题所在。runSQL的类型为:

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

结果类型(HasSpock m, SpockConn m ~ SqlBackend) => m a告诉我们runSQL给出了Spock单子中的结果。因此,loadFlightSeat也应该是Spock单单元计算。但是,您给它指定了类型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

注:

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定义的单子。因此,您给loadFlightSeat的签名会导致编译器尝试将Spock的单子与MarkupM匹配。

相关内容

  • 没有找到相关文章

最新更新