簡體   English   中英

如何正確堆疊monad以最終呈現為html?

[英]How to stack correctly monads to finally render to html?

我的目標是使用HtmlT m類型(最好是Html () )正確地饋送html函數(在Spock-core中定義)。 在這之間,我正在執行一些Network.Http.Simple請求。 顯然我對Haskell的了解不足,我沒有找到強制正確的monad的方法。 據我所知(並理解單子的整體含義),沒有辦法組成不同的單子,例如(Monad M, Monad N => M a -> (a -> N b) -> N b)

我設法達到的最佳效果是設置HtmlT IO ()類型,但隨后陷入轉換函數lucid :: HtmlT IO () -> SpockAction dtb sess state ()

這是我的連接函數( Auth是用於承載授權密鑰和令牌的FromJSON數據結構)

     connect :: IO Auth
     connect = do  
                ...building a http request.. 
                response <- httpJSON request
                return (getResponseBody response :: Auth)

接下來,將其getRequest到類型為String -> HtmlT IO ()getRequest函數中

    getRequest :: RequestPath -> HtmlT IO ()
    getRequest rpath = do
                    atoken <- liftIO connect
                    request' <- liftIO parseRequest "http://......"
                    let request = { series of set methods
                                    to build the request }
                    response <- httpLBS request
                    liftIO (L8.putStrnLn $ (getResponseBody response))

在這里我們介紹了lucid函數,Lucid可以處理Html () -> SpockAction ... Html ()就是HtmlT Identity ()所以我的第一個嘗試是用HtmlT IO ()來提供清醒的HtmlT IO ()

   lucid :: HtmlT IO () -> SpockAction database session state ()
   lucid document = do 
                        txt <- renderTextT document       --> inside IO (?)
                        return html (TL.toStrict txt)     <-- naive attempt to 
                                      return to "somewhere" of course stupid..

IO可能不是這里的好單子嗎? 當我嘗試使用Identity monad(具有HtmlT Identity () )時,如果我將connect定義為connect :: Identity Auth那么很自然地,我會被要求輸入Identity的FromJSON實例(使用httpJSON引起),也許是潛在的解決方案一旦我進入Identity monad,就可以進行連接,並可能以干凈的Html ()類型結束,然后由我的清醒函數平穩地執行它。

感謝您提供的任何線索或提示,也許我的方法是完全錯誤的,整個工作是查詢restAPI網站並在使用Spock運行的Web服務器上查看結果。

相關類型:

document :: HtmlT IO ()
renderTextT :: Monad m => HtmlT m a -> m Text
renderTextT document :: IO Text
<the value you need> :: SpockAction database session state Text

幸運的是,我們有以下可用: liftIO :: MonadIO m => IO a -> ma

運行lucid函數的兩個步驟:

  1. txt <- renderTextT document更改為txt <- liftIO (renderTextT document)
  2. 嘗試編譯您的代碼以確保liftIO已導入(可能已經導入)。 如果不是這樣:將import Control.Monad.IO.Class添加到您的導入列表。
  3. return html (TL.toStrict txt)刪除return

以下代碼在我的計算機上運行:

lucid :: HtmlT IO () -> SpockAction database session state ()
lucid document = do
  txt <- liftIO (renderTextT document)
  html (TL.toStrict txt)

暫無
暫無

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

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