title: How to write stateful dbus methods in haskell?
body: <p>I'm working with <a href="https://www.stackage.org/lts-11.3/package/dbus-0.10.15" rel="nofollow noreferrer">dbus</a> in haskell, and I'm having difficulties figuring out how to export dbus methods that perform stateful operations. Below is a fully fleshed out example to illustrate where I'm stuck.</p>
  <hr />
  <p>Let's say you're writing a counter service with dbus. When the service starts, the counter is initially at 0. The service defines a dbus API that exposes a <code>count</code> method, which returns the current value of the counter, and an <code>update</code> method, which increments that counter, and returns the new value.</p>
  <p>Here's a pseudocodey implementation of the behavior I just described, using a message-passing-style of communication:</p>
  <pre class="lang-hs prettyprint-override"><code>-- | Updates the given integer. 
  update :: Int -&gt; Int
  update = (+1)
  
  -- | main function with message-passing-style communication
  mainLoop :: Int -&gt; IO Int
  mainLoop state = do
    case receiveMessage of
      &quot;update&quot; -&gt; do -- increment / update counter
        sendReply $ update state
        mainLoop $ update state -- recurse
      &quot;count&quot; -&gt; do -- return counter value
        sendReply state
        mainLoop state
      &quot;stop&quot; -&gt; do -- stop the counting service
        exitSuccess
  
  main :: IO ()
  main = do
    mainLoop 0
  </code></pre>
  <p>However, dbus uses method-calls, not message passing. So, I need to be able to <a href="https://www.stackage.org/haddock/lts-11.3/dbus-0.10.15/DBus-Client.html#v:export" rel="nofollow noreferrer">export</a> a <code>count</code> and <code>update</code> method that behaves the same way as in my message-passing example.</p>
  <p>The stub we'll work with is something like this:</p>
  <pre class="lang-hs prettyprint-override"><code>-- | Updates the given integer. 
  update :: Int -&gt; Int
  update = (+1)
  
  main :: IO ()
  main = do
    let initialState = 0
    dbus &lt;- connectSession
    export dbus &quot;/org/counter/CounterService&quot;
      [ autoMethod &quot;org.counter.CounterService&quot; &quot;update&quot; ({-- call update? --})
      , autoMethod &quot;org.counter.CounterService&quot; &quot;count&quot; ({-- return state? --}) ]
  </code></pre>
  <p>And here lies my question: <strong>How should I encode the missing <code>{-- call update? --}</code> and <code>{-- return state? --}</code> functions?</strong></p>
  <p>I know I can use an <code>MVar</code> to create global mutable state, and then just make the functions read from that, but I want to avoid mutability as much as possible here. I <em>think</em> I can do this with the Reader/State monad somehow, maybe by sneaking a <code>get</code>/<code>ask</code> into the functions, but I don't know how to handle the types with respect to DBus.</p>