State monad是否需要/在具有可变(局部)变量(例如Scala)的语言中有用? [英] Is State monad needed/useful in a language with mutable (local) variables (such as Scala)?

查看:61
本文介绍了State monad是否需要/在具有可变(局部)变量(例如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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆