Can the state monad be used for self-modifying functions?

I would like to present the self-modification function in a functional manner, which led me to consider the state monad. The version from the book "Functional Programming in Scala" is essentially a case class wrapper for the function S => (R, S), where S is the state and R is the result. For example, it works with this random number generator like this:

trait RNG {
    def nextInt : Int
}

case State[S,R]( run : S => (R,S) ) { /* other details omitted */ }

type Rand[R] = State[RNG,R] // `random generator of R'

      

So this all works great, since we don't need any parameters other than RNG (part of the state) to return R (part of the result).

For a self-modifying function, the desire is to use the state monad to come up with a more syntactically-arid version of the following:

trait Fn[A,R] {
   def apply(a: A): (R,Fn[A,R])
}

      

and ideally this could be done with map

and methods flatMap

(which could then be automatically included through Scala for notation).

However, unlike Rand's example, Fn takes an argument of type A.

Is such a thing still conceivable using the state monad? If not, can it be expressed as monand, and if so, how would one write any map or flatMap considered fundamental *?

* I mention this last point because the FPiS monad trait seems to treat the map as a rudimentary operation.

+3


source to share


1 answer


It should be good; the obvious approach will work:



def applyState[A, R](a: A) = State(fn: Fn[A, R] => fn.apply(a))

val composedState = for {
  firstResult <- applyState[Int, Thingy](2)
  secondResult <- applyState[Int, Thingy](4)
} yield secondResult

composedState.run(new Fn[Int, Thingy]{...})

      

+3


source







All Articles