Я только начинаю веб-разработку Haskell с помощью Spock, persistent и blaze-html.Ошибка типа Blaze-html внутри forM_ block
В одном из маршрутов, которые у меня есть, я хочу загрузить каждую строку в мои выбранные таблицы. Я делаю что-то вроде этого:
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))
Я скопировал 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
обертка от стойких к Споку, и если я просто хочу, чтобы выходной HTML, почему не может он проходит проверку типа?
Как устранить этот тип ошибки?
Спасибо, кажется, что перемещение loadFlightSeat работает. Хотя у меня все еще есть путаница в том, почему я должен переместить ее в монадию Спока (несмотря на то, что это такая же монада). Еще раз спасибо! – SanShin
@SanShin Если я правильно понимаю ваше сомнение, кажется, вы смешиваете что-то, находящееся в 'do' -блоке какой-то монады, когда он находится в предложении' where' ниже 'do'-block. Для целей вашего вопроса не имеет значения, где вы определяете значение типа 'loadFlightSeat' (т. Е. Находится ли он на верхнем уровне,' where', выражение 'let' и т. Д.).То, что определяет, к какой монаде принадлежит значение, и как вам нужно использовать, - это его тип. – duplode