假设我有一个记录,其中一个值是一个MVar:
data SomeRecord = SomeRecord { frobs :: MVar Integer }
Run Code Online (Sandbox Code Playgroud)
我希望能够使用Aeson从JSON编码/解码它.在编码时,MVar将被解包并且原始值被编码,并且在解码时将发生相反的情况.
能够只写一个返回的IO (Maybe SomeRecord)FromJSON实例和一个返回的ToJSON实例会很好IO ByteString,但由于Parser monad不是MonadIO的实例,我认为不可能.
到目前为止,我已经尝试编写函数来在MVar-encumbered记录和几乎没有MVar类型的相同记录之间进行转换,然后对其进行编码/解码.
我试图找到一些方法来保持MVar首先脱离我的记录.这似乎是理想的.但是假设我出于某种原因无法做到这一点,是否有更简单的方法来处理JSON编码/解码?
编辑:
我想知道我是不是在问错误的问题.也许我的整个方法都不正确.我要做的是允许一堆连接的客户端(每个在不同的线程上)添加/编辑/删除对象列表.这是类型的样子:
-- the data type for each "room"
data Instance = Instance
{ iName :: T.Text
, iObjects :: M.HashMap T.Text (MVar Store)
...
}
-- the data type for a particular object in the room that can be changed
data Store = Store
{ sObject :: A.Value
...
}
Run Code Online (Sandbox Code Playgroud)
每个"房间"都有一个Instance房间对象.实例本身位于MVar中以同步iObjects散列映射的添加/删除,并且每个单独的存储都在MVar中,以便在更新单个对象时不必阻止整个数据结构.
所以更新操作如下所示:
有没有比使用这样的嵌套MV更惯用的haskell方法?理想情况下,某种方式可以使MVar远离数据,因此保持整个结构很简单.
不,您有一个隐藏在纯数据结构中的并发原语.处理起来总是有点尴尬.你将副作用走私到试图接触你的MVar的任何东西.
尝试通过容器为Integer参数化数据类型.例如
data T a = T { frobs :: c Integer }
Run Code Online (Sandbox Code Playgroud)
那么你就可以工作,它实例化T MVar,并为流媒体,拆开包装,然后在其上运行的T One,在那里data One a = One a.