我在 haskell 中使用dbus,我很难弄清楚如何导出执行有状态操作的 dbus 方法。下面是一个完整的例子来说明我卡在哪里。
假设您正在使用 dbus 编写计数器服务。当服务启动时,计数器最初为 0。服务定义了一个 dbus API,它公开了一个count
方法,该方法返回计数器的当前值,以及一个update
方法,该方法递增该计数器并返回新值。
这是我刚刚描述的行为的伪代码实现,使用消息传递样式的通信:
-- | Updates the given integer.
update :: Int -> Int
update = (+1)
-- | main function with message-passing-style communication
mainLoop :: Int -> IO Int
mainLoop state = do
case receiveMessage of
"update" -> do -- increment / update counter
sendReply $ update state
mainLoop $ update state -- recurse
"count" -> do -- return counter value
sendReply state
mainLoop state
"stop" -> do -- stop the counting service
exitSuccess
main :: IO ()
main = do
mainLoop 0
但是,dbus 使用方法调用,而不是消息传递。所以,我需要能够导出一个count
和update
我的消息传递示例中行为方式相同的方法。
我们将使用的存根是这样的:
-- | Updates the given integer.
update :: Int -> Int
update = (+1)
main :: IO ()
main = do
let initialState = 0
dbus <- connectSession
export dbus "/org/counter/CounterService"
[ autoMethod "org.counter.CounterService" "update" ({-- call update? --})
, autoMethod "org.counter.CounterService" "count" ({-- return state? --}) ]
这就是我的问题:我应该如何编码缺失{-- call update? --}
和{-- return state? --}
功能?
我知道我可以使用 anMVar
创建全局可变状态,然后从中读取函数,但我想在这里尽可能避免可变性。我想我可以用 Reader/State monad 以某种方式做到这一点,也许通过将get
/偷偷ask
带入函数中,但我不知道如何处理与 DBus 相关的类型。