2
votes

I'm coding a http client as a learning project with the use of network-http package (http://hackage.haskell.org/package/HTTP-4000.2.2) .

There is a Network.Browser module which defines getBrowserState function.

Probably just a lame beginner question but how can I get BrowserState record from BrowserAction monad if Network.Browser module does not export data constructor or record's lift function ?

import Network.Browser

-- getBrowserState :: BrowserAction t (BrowserState t)

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

In addition what about further handling of BrowserState fields like bsCookies, bsDebug, bsProxy etc. ? (http://hackage.haskell.org/packages/archive/HTTP/4000.2.2/doc/html/src/Network-Browser.html#BrowserState)

1

1 Answers

4
votes

What you're trying to do doesn't really make sense. A BrowserAction describes an action, while a BrowserState describes the current state of the browser at some point within an action.

The only way of getting something out of a BrowserAction is to run it with the browse function.

browse :: BrowserAction conn a -> IO a

It's essentially the same as why you can't get a Something out of an IO Something, except here you have the function browse which allows you to "get stuff out of" a browser action by running it.

For example, you can make an action that extracts the current browser state after the original action and run that:

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

Note the IO in the type here, as running the action may have side effects.

That said, I suspect that what you really want is to make the code that needs the current browser state part of an action.

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

Note that BrowserAction has a MonadIO instance, so you can still do IO stuff by using liftIO.

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

In other words, you shouldn't think of it as getting stuff out of a BrowserAction. You should instead think of how to make the browsing-related code part of a BrowserAction which you then run with browse.