Thursday, April 14, 2011

ScalaFp 03 (State)






Expect frequent changes.





State


Here is an aspect of computations: state.


Here is StateModule.
The abstract state methods are _get and _set.






package com.imaginej

package state

trait StateModule {
type S
type M[+Z] <: State[Z]
def _get: Unit => M[S]
def _set: S => M[Unit]
trait State[+A] { self: M[A] =>
}
}




StateMonads


The extra concrete state monad method is _do.






package com.imaginej

package monad

package state

import monad.MonadModule
import com.imaginej.state.StateModule

trait StateMonadModule
extends MonadModule
with StateModule {
def _do: (S => S) => M[Unit] =
f =>
for {
s <- _get(())
u <- _set(f(s))
} yield u
type M[+Z] <: StateMonad[Z]
trait StateMonad[+A]
extends Monad[A]
with State[A] { self: M[A] =>
}
}




Transformed Monads


Monads can be transformed.


Here is TransformedMonadModule.
It makes use of an implicit monadObject.
The abstract transformed monad method is _lift.
There are also abstract openT and _closeT methods.
The abstract method _return can now be defined.






package com.imaginej

package monad

package transformed

import monad.MonadModule

trait TransformedMonadModule
extends MonadModule {
type MonadModuleType <: MonadModule
implicit val monadObject: MonadModuleType
type FromM[+Z] = monadObject.M[Z]
type FromIn[Z] = monadObject.In[Z]
type FromOut[Z] = monadObject.Out[Z]
def _fromReturn[Z]: Z => FromM[Z] =
monadObject._return(_)
type M[+Z] <: TransformedMonadTrait[Z]
type ToM[+Z]
def _closeT[Z]: ToM[Z] => M[Z]
def _lift[Z]: FromM[Z] => ToM[Z]
def _liftT[Z] =
_lift[Z] andThen _closeT[Z]
override def _return[Z] =
z =>
_liftT {
_fromReturn(z)
}
trait TransformedMonadTrait[+A]
extends Monad[A] { self: M[A] =>
def openT: ToM[A]
}
}




State Transformed Monads


Here is StateTransformedMonadModule.
It makes use of a type ToM[+Z] = S => FromM[(Z, S)].
The abstract methods flatMap, _get, _set and _lift can now be defined.
Also a method runState is defined.






package com.imaginej

package monad

package state.transformed

import com.imaginej.monad.state.StateMonadModule
import com.imaginej.monad.transformed.TransformedMonadModule

trait StateTransformedMonadModule
extends TransformedMonadModule
with StateMonadModule {
type M[+Z] <: StateTransformedMonadTrait[Z]
type ToM[+Z] = S => FromM[(Z, S)]
type In[-Z] = S
override def _lift[Z] =
mz => s =>
mz flatMap { z =>
_fromReturn((z, s))
}
override def _get =
_ =>
_closeT { s =>
_fromReturn((s, s))
}
override def _set =
s =>
_closeT { _ =>
_fromReturn(((), s))
}
trait StateTransformedMonadTrait[+A]
extends TransformedMonadTrait[A]
with StateMonad[A] { self: M[A] =>
override def flatMap[B](a_f_mb: A => M[B]) =
_closeT { s =>
this.openT(s) flatMap {
case (a, s) =>
a_f_mb(a) openT s
}
}
def runState[B >: A](s: S)(i: FromIn[(B, S)]): FromOut[(B, S)] =
this openT s run i
}
}




State Transformed Monad Instances


Here is a state transformed monad instance.







StateTransformedIdentityMonad.






package com.imaginej

package monad

package state.instances

import monad.instances.IdentityMonadObject
import monad.state.transformed.StateTransformedMonadModule

abstract class StateTransformedIdentityMonadModule(
implicit override val monadObject: IdentityMonadObject.type )
extends StateTransformedMonadModule {
type MonadModuleType = IdentityMonadObject.type
type M[+Z] = StateTransformedIdentityMonad[Z]
type Out[+Z] = (Z, S)
def _closeT[Z] =
StateTransformedIdentityMonad[Z](_)
case class StateTransformedIdentityMonad[+A](
val openT: S => IdentityMonadObject.M[(A, S)])
extends StateTransformedMonadTrait[A] {
def run[B >: A](s: S): (B, S) =
runState(s) ()
}
}

import monad.MonadModule.identityMonad

object IntStateTransformedIdentityMonadObject
extends StateTransformedIdentityMonadModule {
type S = Int
}




Implicit State Transformed Monads


It is convenient to define implicit state transformed monads for later usage.






import instances.IntStateTransformedIdentityMonadObject

object StateMonadModule {
implicit def intStateTransformedIdentityMonadObject =
IntStateTransformedIdentityMonadObject
}




Application


Here is an application.






package com.imaginej

package apps

import monad.state.instances._

object UsingStateMonads {
def usingStateTransformedIdentityMonad() {
import IntStateTransformedIdentityMonadObject._
val computation1 =
for {
s <- _get(())
_ <- _do(_ + 1)
} yield s + 1
println {
computation1 run 0
}
val computation2 =
for {
_ <- _do(_ + 1)
s <- _get(())
} yield s + 1
println {
computation2 run 0
}
}
def main(args: Array[String]) {
usingStateTransformedIdentityMonad()
}
}





Running the application yields.




$ scala com.imaginej.apps.UsingStateMonads
(1,1)
(2,1)




Transformed ChoiceMonads


Choice monads can be transformed.


Here is TransformedChoiceMonadModule.
The abstract method _nothing can now be defined.






package com.imaginej

package monad

package choice

package transformed

import monad.choice.ChoiceMonadModule
import monad.transformed.TransformedMonadModule

trait TransformedChoiceMonadModule
extends TransformedMonadModule
with ChoiceMonadModule {
override type MonadModuleType <: ChoiceMonadModule
def _fromNothing[Z]: FromM[Z] =
monadObject._nothing
override def _nothing[Z] =
_liftT {
_fromNothing
}
type M[+Z] <: TransformedChoiceMonadTrait[Z]
trait TransformedChoiceMonadTrait[+A]
extends TransformedMonadTrait[A]
with ChoiceMonad[A] { self: M[A] =>
}




State Transformed Choice Monads


Here isStateTransformedChoiceMonadModule.
The abstract method or can now be defined.






package com.imaginej

package monad

package state.transformed

import monad.state.StateMonadModule
import monad.choice.transformed.TransformedChoiceMonadModule

trait StateTransformedChoiceMonadModule
extends TransformedChoiceMonadModule
with StateTransformedMonadModule {
type M[+Z] <: StateTransformedChoiceMonadTrait[Z]
trait StateTransformedChoiceMonadTrait[+A]
extends TransformedChoiceMonadTrait[A]
with StateTransformedMonadTrait[A] { self: M[A] =>
override def or[B >: A](mb: => M[B]): M[B] =
_closeT { s =>
this.openT(s) or mb.openT(s)
}
}
}




State Transformed Choice Monad Instances


Here are some state transformed choice monad instances.







StateTransformedTraversableChoiceMonadModule.






package com.imaginej

package monad

package choice

package state.instances

import instances.TraversableChoiceMonadObject
import monad.state.transformed.StateTransformedChoiceMonadModule

abstract class StateTransformedTraversableChoiceMonadModule(
implicit override val monadObject: TraversableChoiceMonadObject.type )
extends StateTransformedChoiceMonadModule {
type MonadModuleType = TraversableChoiceMonadObject.type
type M[+Z] = StateTransformedTraversableChoiceMonad[Z]
type Out[+Z] = Traversable[(Z, S)]
def _closeT[Z] =
StateTransformedTraversableChoiceMonad[Z](_)
case class StateTransformedTraversableChoiceMonad[+A](
val openT: S => TraversableChoiceMonadObject.M[(A, S)])
extends StateTransformedChoiceMonadTrait[A] {
def run[B >: A](s: S): Traversable[(B, S)] =
runState(s) ()
}
}

import monad.choice.ChoiceMonadModule.traversableChoiceMonad

object IntStateTransformedTraversableChoiceMonadObject
extends StateTransformedTraversableChoiceMonadModule {
type S = Int
}





StateTransformedOptionChoiceMonadModule.






package com.imaginej

package monad

package choice

package state.instances

import instances.OptionChoiceMonadObject
import monad.state.transformed.StateTransformedChoiceMonadModule

abstract class StateTransformedOptionChoiceMonadModule(
implicit override val monadObject: OptionChoiceMonadObject.type )
extends StateTransformedChoiceMonadModule {
type MonadModuleType = OptionChoiceMonadObject.type
type M[+Z] = StateTransformedOptionChoiceMonad[Z]
type Out[+Z] = Option[(Z, S)]
def _closeT[Z] =
StateTransformedOptionChoiceMonad[Z](_)
case class StateTransformedOptionChoiceMonad[+A](
val openT: S => OptionChoiceMonadObject.M[(A, S)])
extends StateTransformedChoiceMonadTrait[A] {
def run[B >: A](s: S): Option[(B, S)] =
runState(s) ()
}
}

import monad.choice.ChoiceMonadModule.optionChoiceMonad

object IntStateTransformedOptionChoiceMonadObject
extends StateTransformedOptionChoiceMonadModule {
type S = Int
}




Implicit State Transformed Choice Monads


It is convenient to define implicit state transformed choice monads for later usage.






import instances.IntStateTransformedIdentityMonadObject
import monad.choice.state.instances.IntStateTransformedTraversableChoiceMonadObject
import monad.choice.state.instances.IntStateTransformedOptionChoiceMonadObject

object StateMonadModule {
implicit def intStateTransformedIdentityMonadObject =
IntStateTransformedIdentityMonadObject
implicit def intStateTransformedTraversableChoiceMonadObject =
IntStateTransformedTraversableChoiceMonadObject
implicit def intStateTransformedOptionChoiceMonadObject =
IntStateTransformedOptionChoiceMonadObject
}




Application


Here is an application.






package com.imaginej

package apps

import monad.choice.state.instances._

object UsingStateAndChoiceMonads {
def usingStateTransformedOptionChoiceMonad() {
import IntStateTransformedOptionChoiceMonadObject._
val computation1 =
_nothing or {
for {
_ <- _do(_ + 1)
s <- _get(())
} yield s
}
println {
computation1 run 0
}
val computation2 =
_nothing or {
for {
s <- _get(())
_ <- _do(_ + 1)
} yield s
}
println {
computation2 run 0
}
}
def usingStateTransformedTraversableChoiceMonad1() {
import IntStateTransformedTraversableChoiceMonadObject._
val computation1 =
_nothing or {
for {
_ <- _do(_ + 1)
s <- _get(())
} yield s
}
println {
computation1 run 0
}
val computation2 =
_nothing or {
for {
s <- _get(())
_ <- _do(_ + 1)
} yield s
}
println {
computation2 run 0
}
}
def usingStateTransformedTraversableChoiceMonad2() {
import IntStateTransformedTraversableChoiceMonadObject._
val computation1 =
for {
s <- _get(())
} yield s
val computation2 =
for {
s <- _get(())
} yield s + 1
val computation =
computation1 or computation2
println {
computation run 0
}
}
def usingStateTransformedTraversableChoiceMonad3() {
import IntStateTransformedTraversableChoiceMonadObject._
val computation1 =
for {
s <- _get(())
} yield (s + 1)
val computation2 =
for {
_ <- _do(_ + 1)
_ <- _do(_ + 1)
s <- _get(())
} yield (s + 1)
val computation =
computation1 or computation2
println {
computation run 0
}
}
def main(args: Array[String]) {
usingStateTransformedOptionChoiceMonad()
usingStateTransformedTraversableChoiceMonad1()
usingStateTransformedTraversableChoiceMonad2()
usingStateTransformedTraversableChoiceMonad3()
}
}





Running the application yields.




$ scala com.imaginej.apps.UsingStateAndChoiceMonads
Some((1,1))
Some((0,1))
List((1,1))
List((0,1))
List((0,0), (1,0))
List((1,0), (3,2))

No comments:

Post a Comment