2012-01-25 42 views
2

我使用網絡http包(http://hackage.haskell.org/package/HTTP-4000.2.2)將http客戶端編碼爲學習項目。如何從BrowserAction monad中提取BrowserState?

有一個Network.Browser模塊定義了getBrowserState函數。

大概只是一個蹩腳的初學者問題,但如何獲取來自BrowserAction monad的BrowserState記錄如果Network.Browser模塊不導出數據構造函數或記錄的提升函數?

import Network.Browser 

-- getBrowserState :: BrowserAction t (BrowserState t) 

extractBS :: BrowserAction t (BrowserState t) -> BrowserState t 
-- ??? implementation ??? 

此外如何進一步處理BrowserState字段,如bsCookies,bsDebug,bsProxy等? (http://hackage.haskell.org/packages/archive/HTTP/4000.2.2/doc/html/src/Network-Browser.html#BrowserState

回答

4

你想要做的事情沒有意義。 A BrowserAction描述了一個動作,而BrowserState描述了動作中某個點上瀏覽器的當前狀態。

BrowserAction中獲取某些東西的唯一方法是使用browse函數運行它。

browse :: BrowserAction conn a -> IO a 

它本質上是一樣的,爲什麼你不能讓一個SomethingIO Something,除了在這裏你有功能browse它允許你運行一下「得到的東西出來的」瀏覽器操作。

例如,可以使原來的動作後,提取當前的瀏覽器狀態的行動,並運行:

browse (action >> getBrowserState) :: IO (BrowserState conn) 

注意IO在這裏的類型,如運行的操作可能有副作用。

這就是說,我懷疑你真正想要的是使需要當前瀏覽器狀態的代碼成爲操作的一部分。

browse $ do action 
      state <- getBrowserState 
      -- do stuff with the state 

注意BrowserActionMonadIO實例,所以你仍然可以通過使用liftIOIO東西。

browse $ do -- browsing 
      liftIO $ putStrLn "foo" 
      -- more browsing 

換句話說,你不應該把它看成獲得的東西出了BrowserAction的。您應該考慮如何製作BrowserAction的瀏覽相關代碼部分,然後使用browse運行該代碼。

+0

感謝您的解釋。我確實懷疑getBrowserState返回一些通常存儲的狀態,而不是當前操作中的狀態。順便說一句。從IO獲取某些東西可以用< - 表達式來完成,但我相信這是你所知道的。 –

+0

@DavidUnric:是的,do-notation可以讓你假裝你已經從monad中取出了一些東西,但是你實際上正在做的是用簡單的東西做出合成動作。除非你運行它,否則你不會得到任何東西。 – hammar

+0

@hammer>是的,如果我思考一段時間,現在我甚至覺得愚蠢,甚至想到haskell中的「全局」/存儲狀態:)提到IO monad的提取也不例外,正如您澄清的那樣。它只是一個monad動作中組合函數的一部分。 –