0
在閱讀Functional Programming in Scala的第6章並試圖瞭解國家monad後,我有一個關於包裝副作用課的問題。包裝帶副作用的課
說我有一個班級,在某種程度上修改自己。
class SideEffect(x:Int) {
var value = x
def modifyValue(newValue:Int):Unit = { value = newValue }
}
我的理解是,如果我們用下面的狀態monad包裝它,它仍然會修改原來的包裝它的想法。
case class State[S,+A](run: S => (A, S)) { // See footnote
// map, flatmap, unit, utility functions
}
val sideEffect = new SideEffect(20)
println(sideEffect.value) // Prints "20"
val stateMonad = State[SideEffect,Int](state => {
state.modifyValue(10)
(state.value,state)
})
stateMonad.run(sideEffect) // run the modification
println(sideEffect.value) // Prints "10" i.e. we have modified the original state
唯一的解決這個,我可以看到的是,使類的副本和修改,但似乎SideEffect增長計算昂貴。另外,如果我們想要包裝一些類似於不實現Cloneable的Java類,我們會很失敗。
val stateMonad = State[SideEffect,Int](state => {
val newState = SideEffect(state.value) // Easier if it was a case class but hypothetically if one was, say, working with a Java library, one would not have this luxury
newState.modifyValue(10)
(newState.value,newState)
})
stateMonad.run(sideEffect) // run the modification
println(sideEffect.value) // Prints "20", original state not modified
我使用State monad是否錯誤?一個人如何去包裝一個副作用的課程,而不必複製它,或者這是唯一的方法?
- 對我使用這裏的國家單子的實施是一本書,並可能從Scalaz實現不同