首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >forM_块中的Blaze-html类型错误

forM_块中的Blaze-html类型错误
EN

Stack Overflow用户
提问于 2015-08-14 02:38:53
回答 1查看 171关注 0票数 0

我刚刚开始Haskell网络开发使用Spock,持久性和熊熊-html。

在其中一条路径中,我希望加载所选表中的每一行。我做了这样的事:

代码语言:javascript
复制
  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的类型:

代码语言:javascript
复制
Integer -> SqlPersistM [Entity Flight]

和getSeatIdByFlight:

代码语言:javascript
复制
T.Text -> Integer -> SqlPersistM (Maybe (Entity Flight))

我从Spock的博客示例应用程序中复制了runSQL,它是这样的:

代码语言:javascript
复制
runSQL :: (HasSpock m, SpockConn m ~ SqlBackend) => SqlPersistT (NoLoggingT (ResourceT IO)) a -> m a
runSQL action = runQuery $ \conn -> runResourceT $ runNoLoggingT $ runSqlConn action conn

我得到的类型错误:

代码语言:javascript
复制
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是一个从persistent到Spock的包装器,如果我只是想输出HTML,为什么它不能通过类型检查呢?

如何解决此类型错误?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-14 03:29:02

免责声明:我没有运行您的代码。

我知道runSQL是从persistent到Spock的包装器。

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

代码语言:javascript
复制
runSQL :: (HasSpock m, SpockConn m ~ SqlBackend)
       => SqlPersistT (NoLoggingT (ResourceT IO)) a -> m a

结果类型(HasSpock m, SpockConn m ~ SqlBackend) => m a告诉我们,runSQL在Spock monad中提供了一个结果。因此,loadFlightSeat也应该是一个Spock计算。但是,您给出了H.Html类型,这与Spock monad无关。如果您删除loadFlightSeat的错误类型签名并相应地调整loadFlightSeat的使用,这个问题可能会消失:

代码语言:javascript
复制
     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

你发现的类型错误..。

代码语言:javascript
复制
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

...is异乎寻常地奇怪,因为H.Html MarkupM ()MarkupMblaze定义的单曲。因此,您给loadFlightSeat的签名导致编译器尝试将Spock的monad与MarkupM匹配。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32001453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档