对于我在Haskell中的矢量图形库,我必须携带一个相当大的状态:线条描边参数,颜色,剪辑路径等.我知道两种方法.引用Haskell-cafe的评论:"我建议你使用具有可变状态的读取器monad,或者使用具有不可变状态的状态monad".
这是我的问题:更新一个大的不可变状态是一个性能杀戮.使用大量的STRef就像在Haskell中编写C一样:它冗长而丑陋.
这是不可变状态:
data GfxState = GfxState {
lineWidth :: Double,
lineCap :: Int,
color :: Color,
clip :: Path,
...
}
setLineWidth :: Double -> State GfxState ()
setLineWidth x = modify (\state -> state { lineWidth = x })
Run Code Online (Sandbox Code Playgroud)
据我所知,"state {lineWidth = x}"创建一个新的GfxState并让旧的GfxState被垃圾收集.当状态很大并经常更新时,这会导致性能下降.
这是可变状态:
data GfxState s = GfxState {
lineWidth :: STRef s Double,
lineCap :: STRef s Int,
color :: STRef s Color,
clip :: STRef s Path,
...
many more STRefs
}
setLineWidth …Run Code Online (Sandbox Code Playgroud)