State monad是否需要/在具有可变(局部)变量(例如Scala)的语言中有用? [英] Is State monad needed/useful in a language with mutable (local) variables (such as Scala)?
问题描述
我了解到,在Haskell中,State monad很有用,因为没有可变变量(除非我们在IO monad中).
I understand that in Haskell the State monad is useful because there are no mutable variables (unless we are in the IO monad).
但是,与Scala有何关系?State Monad在存在可变变量的语言中有用吗?
However, what is the deal with Scala ? Is State Monad useful in a language where there are mutable variables ?
In some sense all the State Monad allows is to use some local mutable variables within the Monad context. For example here:
newtype Labeled anytype = Labeled (S -> (S, anytype))
instance Monad Labeled where
return contents = Labeled (\st -> (st, contents))
Labeled fst0 >>= fany1 =
Labeled $ \st0 ->
let (st1, any1) = fst0 st0
Labeled fst1 = fany1 any1
in fst1 st1
mlabel :: Tr anytype -> Lt anytype
mlabel tr = let Labeled mt = mkm tr
in snd (mt 0)
mkm :: Tr anytype -> Labeled (Lt anytype)
mkm (Lf x)
= updateState >>= \n -> return $ Lf (n,x)
mkm (Br l r)
= mkm l >>= \l' ->
mkm r >>= \r' ->
return $ (Br l' r')
updateState :: Labeled S
updateState = Labeled (\n -> ((n+1),n))
main = print $ mlabel tr1
使用Scala中的可变变量,此代码将更加简单(3-4行).就像是:案例类Tr(...)
This code would be much simpler (3-4 lines) using mutable variables in Scala. Something like:
case class Tr (...)
案例类LTr(...)
def labelTree =(...递归调用...)
其中 labelTree
使用本地可变变量来存储标签的当前状态.
where labelTree
is using local mutable variables to store the current state of the label.
我真的看不到Scala中State Monads的用处.为什么有人会在Scala中使用State Monad?有没有很好的用例呢?
I don't really see the usefulness of State Monads in Scala. Why would anyone use State Monad in Scala ? Are there any good use cases for it ?
我可以想象的唯一用例是,有状态计算是复杂的并且是由多个State Monad组成的,但是到那时,我不确定与普通的旧函数编程和显式参数相比,使用State Monad有多大用处传递(而不是隐式参数传递,这就是State Monad).
The only use case I can imagine if the stateful computation is complex and is composed from several State Monads, but at that point I am not sure how useful it is to use State Monad in contrast to plain old functional programming and explicit argument passing (instead of implicit argument passing which is what the State Monad is).
推荐答案
在Haskell中编写有状态动作时,有一个习惯用法,即动作只要求知道完成任务所需的最低限度的状态,然后才知道每个动作已放大复合的全局状态".例如:
When composing stateful actions in Haskell, there is an idiom in which actions only demand to know the bare minimum of state needed to accomplish their tasks, and then each action is zoomed into a composite "global state". For example:
import Control.Lens
import Control.Monad.Trans.State
succInt :: StateT Int IO String
succInt = do
modify succ
return "Incr an Int!"
succChar :: StateT Char IO String
succChar = do
modify succ
return "Incr a Char!"
type GlobalState = (Char,[Int])
composite :: StateT GlobalState IO (String,String)
composite = do
r1 <- zoom _1 succChar
r2 <- zoom (_2.traversed) succInt
return (r1,r2)
如果我们执行这样的示例:
If we execute the example like this:
ghci> runStateT composite ('a',[1,5,7])
结果是
(("Incr a Char!","Incr an Int!Incr an Int!Incr an Int!"),('b',[2,6,8]))
我认为使用可变变量很难将状态放大"为更大的状态.
I think the "zooming" of the states into bigger states would be more difficult to accomplish with mutable variables.
这篇关于State monad是否需要/在具有可变(局部)变量(例如Scala)的语言中有用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!