Friday, April 15, 2011

ScalaFp 04 (Control)






Expect frequent changes.





Control


Here is an aspect of computations: control.


Here is ControlModule.
The abstract control methods are _withC, pushC and pushP.
The extra concrete control methods are _resetC and _shiftC.






package com.imaginej

package control

trait ControlModule {
type M[+Z] <: Control[Z]
type P[Z]
type C1[Y, Z] = M[Y] => M[Z]
type C2[Y, Z] = C1[Y, Z] => M[Z]
type C3[Y, Z] = C2[Y, Z] => M[Y]
def _withC[Y, Z](implicit p: P[Z]): C3[Y, Z]
def _resetC[Z](implicit p: P[Z]): M[Z] => M[Z] =
_.pushP
def _shiftC[Y, Z](implicit p: P[Z]): C3[Y, Z] =
c2 =>
_withC apply { (c1: C1[Y, Z]) =>
c2(_.pushC(c1).pushP).pushP
}
trait Control[+A] { self: M[A] =>
def pushC[C >: A, B, D >: B](c1: C1[C, D]): M[D]
def pushP[B >: A](implicit p: P[B]): M[B]
}
}




ControlMonads


The extra concrete control monad methods are _withCC and _shiftCC.
Also extra methods like reflect and * can be defined.






package com.imaginej

package monad

package control

import monad.MonadModule
import com.imaginej.control.ControlModule

trait ControlMonadModule
extends MonadModule
with ControlModule {
type M[+Z] <: ControlMonad[Z]
type CC1[Y, Z] = Y => M[Z]
type CC2[Y, Z] = CC1[Y, Z] => M[Z]
type CC3[Y, Z] = CC2[Y, Z] => M[Y]
private def c2cc[Y, Z](implicit p: P[Z]): C3[Y, Z] => CC3[Y, Z] =
f => c3 =>
f apply { (c1: C1[Y, Z]) =>
val c2 = (y: Y) => c1(_return(y))
c3(c2)
}
def _withCC[Y, Z](implicit p: P[Z]): CC3[Y, Z] =
c2cc apply _withC
def _shiftCC[Y, Z](implicit p: P[Z]): CC3[Y, Z] =
c2cc apply _shiftC
trait ControlMonad[+A]
extends Monad[A]
with Control[A] { self: M[A] =>
def reflect[C >: A, B](implicit p: P[B]): M[C] =
_shiftCC apply { (sc: C => M[B]) =>
this flatMap sc
}
def *[C >: A, B](mb: M[B])(implicit p: P[(C, B)]): M[(C, B)] =
for {
c <- this.reflect
b <- mb.reflect
} yield (c, b)
}
}




Control Transformed Monads


Here is controlTransformedMonadModule.
It makes use of a type ToM[+Z] = FromM[ValOrExc[M, Z]].
The abstract methods flatMap, _withC, pushC and pushP can now be defined.
Also a method runSControl is defined.


Note: The definition of _withC makes use of asInstanceOf.






package com.imaginej

package monad

package control.transformed

import monad.control.ControlMonadModule
import monad.transformed.TransformedMonadModule

trait ControlTransformedMonadModule
extends TransformedMonadModule
with ControlMonadModule {
type M[+Y] <: ControlTransformedMonadTrait[Y]
type Ans
type Res
case class Prompt[M[_], Z](
_1: C2[Ans, Z] => C2[Ans, Res],
_2: C2[Ans, Res] => Option[C2[Ans, Z]])
type P[Z] = Prompt[M, Z]
implicit val prompt: P[Res] =
Prompt(identity, Some(_))
// note: do not start with underscore
def resetC(m_r: M[Res]): M[Res] =
_resetC apply m_r
def shiftC(c2: C2[Ans, Res]) =
_shiftC apply c2
def shiftCC(cc2: CC2[Ans, Res]) =
_shiftCC apply cc2
//
trait ValOrExc[M[_], +Z]
case class Val[M[_], +Z](z: Z) extends ValOrExc[M, Z]
case class Exc[M[_], Z](
c1: C1[Ans, Z],
c2: C2[Ans, Res]) extends ValOrExc[M, Z]
type ToM[+Z] = FromM[ValOrExc[M, Z]]
type In[-Z] = Unit
override def _lift[Z] =
_.map(Val(_))
// note: only place where asInstanceOf is used
def _withC[Y, Z](implicit p: P[Z]): C3[Y, Z] =
c2 =>
_closeT {
_fromReturn {
Exc(
((my: M[Y]) => my).asInstanceOf[C1[Ans, Y]],
p._1(c2.asInstanceOf[C2[Ans, Z]]))
}
}
trait ControlTransformedMonadTrait[+A]
extends TransformedMonadTrait[A]
with ControlMonad[A] { self: M[A] =>
override def flatMap[B](af_mb: A => M[B]) = {
_closeT {
this.openT flatMap {
case Val(a) =>
af_mb(a).openT
case Exc(c1, c2) =>
_fromReturn(Exc(c1(_).flatMap(af_mb), c2))
}
}
}
override def pushC[C >: A, B, D >: B](c: C1[C, D]): M[D] =
c(this)
override def pushP[D >: A](implicit p: P[D]): M[D] = {
_closeT {
this.openT flatMap {
case v@Val(_) =>
_fromReturn(v)
case Exc(c1, c2) =>
p._2(c2) match {
case someC2@Some(_) =>
someC2.get(c1).openT
case None =>
_fromReturn(Exc(c1(_).pushP(p), c2))
}
}
}
}
def runControl[B >: A](u: Unit)(i: FromIn[B]): FromOut[B] = {
this.openT flatMap {
case Val(b) =>
_fromReturn(b)
case Exc(_, _) =>
throw new Exception("you forgot to push a prompt")
} run i
}
}
}




Control Transformed Monad Instances


Here are some control transformed monad instances.







ControlTransformedIdentityMonad.






package com.imaginej

package monad

package control.instances

import instances.IdentityMonadObject
import control.transformed.ControlTransformedMonadModule

abstract class ControlTransformedIdentityMonadModule(
implicit override val monadObject: IdentityMonadObject.type )
extends ControlTransformedMonadModule {
type MonadModuleType = IdentityMonadObject.type
type M[+Z] = ControlTransformedIdentityMonad[Z]
type Out[+Z] = Z
def _closeT[Z] =
ControlTransformedIdentityMonad[Z](_)
case class ControlTransformedIdentityMonad[+A](val openT: ToM[A])
extends ControlTransformedMonadTrait[A] {
def run[B >: A](u: Unit): B =
runControl(u) ()
}
}

import monad.MonadModule.identityMonad

object Int_Int_ControlTransformedIdentityMonadObject
extends ControlTransformedIdentityMonadModule {
type Ans = Int
type Res = Int
}

object Unit_Int_ControlTransformedIdentityMonadObject
extends ControlTransformedIdentityMonadModule {
type Ans = Unit
type Res = Int
}

object Int_Unit_ControlTransformedIdentityMonadObject
extends ControlTransformedIdentityMonadModule {
type Ans = Int
type Res = Unit
}

object Unit_Unit_ControlTransformedIdentityMonadObject
extends ControlTransformedIdentityMonadModule {
type Ans = Unit
type Res = Unit
}





ControlTransformedTraversableMonad.






package com.imaginej

package monad

package control.instances

import instances.TraversableMonadObject
import control.transformed.ControlTransformedMonadModule

abstract class ControlTransformedTraversableMonadModule(
implicit override val monadObject: TraversableMonadObject.type)
extends ControlTransformedMonadModule {
type MonadModuleType = TraversableMonadObject.type
type M[+Z] = ControlTransformedTraversableMonad[Z]
type Out[+Z] = Traversable[Z]
def _closeT[Z] =
ControlTransformedTraversableMonad[Z](_)
case class ControlTransformedTraversableMonad[+A](val openT: ToM[A])
extends ControlTransformedMonadTrait[A] {
def run[B >: A](u: Unit): Traversable[B] =
runControl(u) ()
}
}

import monad.MonadModule.traversableMonad

object Int__Int_Char_ControlTransformedTraversableMonadObject
extends ControlTransformedTraversableMonadModule {
type Ans = Int
type Res = (Int, Char)
}

object Unit_Unit_ControlTransformedTraversableMonadObject
extends ControlTransformedTraversableMonadModule {
type Ans = Unit
type Res = Unit
}




Implicit Control Transformed Monads


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






import instances.Int_Int_ControlTransformedIdentityMonadObject
import instances.Unit_Int_ControlTransformedIdentityMonadObject
import instances.Int_Unit_ControlTransformedIdentityMonadObject
import instances.Unit_Unit_ControlTransformedIdentityMonadObject
import instances.Int__Int_Char_ControlTransformedTraversableMonadObject
import instances.Unit_Unit_ControlTransformedTraversableMonadObject

object ControlMonadModule {
implicit def int_Int_ControlTransformedIdentityMonadObject =
Int_Int_ControlTransformedIdentityMonadObject
implicit def unit_Int_ControlTransformedIdentityMonadObject =
Unit_Int_ControlTransformedIdentityMonadObject
implicit def int_Unit_ControlTransformedIdentityMonadObject =
Int_Unit_ControlTransformedIdentityMonadObject
implicit def unit_Unit_ControlTransformedIdentityMonadObject =
Unit_Unit_ControlTransformedIdentityMonadObject
implicit def int__Int_Char_ControlTransformedTraversableMonadObject =
Int__Int_Char_ControlTransformedTraversableMonadObject
implicit def unit_Unit_ControlTransformedTraversableMonadObject =
Unit_Unit_ControlTransformedTraversableMonadObject
}





Application


Here is an application.






package com.imaginej

package apps

object UsingControlMonads {

import monad.control.instances._

def usingInt_Int_ControlTransformedIdentityMonad() {
import Int_Int_ControlTransformedIdentityMonadObject._
lazy val computation =
resetC {
shiftCC { c =>
c(7)
} >= { i =>
_return(i + 1)
} >= { j =>
_return(2 * j)
}
}
println {
computation run ()
}
}
def usingInt_Unit_ControlTransformedIdentityMonad() {
import Int_Unit_ControlTransformedIdentityMonadObject._
lazy val computation =
resetC {
shiftCC { c =>
c(7)
_return(())
} >= { i =>
_return(i + 1)
} >= { j =>
_return(2 * j)
}
}
println {
computation run ()
}
}
def usingInt__Int_Char_ControlTransformedTraversableMonad() {
import monad.instances.TraversableMonadObject._close
import Int__Int_Char_ControlTransformedTraversableMonadObject._
implicit def traversableToM[Z](zs: Traversable[Z]): M[Z] =
_liftT(_close(zs))
val computation =
resetC {
List(1, 2) * List('a', 'b')
}
println {
computation run ()
}
}
def usingUnit_Unit_ControlTransformedIdentityMonad() {
import Unit_Unit_ControlTransformedIdentityMonadObject._
def _println(s: String) = _return(println(s))
lazy val computation =
resetC {
println("A")
shiftCC { c =>
println("B")
c()
_println("C")
} >> {
println("D")
shiftCC { c =>
println("E")
c()
_println("F")
} >>
_println("G")
}
}
computation run ()
import java.util.{ Timer, TimerTask }
resetC {
println(" look, Ma ...")
shiftCC { c =>
println("wait 5 secs ...")
new Timer().schedule(new TimerTask {
def run() = c()
}, 5000)
_return(())
} >> {
_println("... no threads!")
}
} run ()
}
def main(args: Array[String]) {
usingInt_Int_ControlTransformedIdentityMonad()
usingInt_Unit_ControlTransformedIdentityMonad()
usingInt__Int_Char_ControlTransformedTraversableMonad()
usingUnit_Unit_ControlTransformedIdentityMonad()
}
}





Running the application yields.




$ scala com.imaginej.apps.UsingControlMonads
16
()
List((1,a), (1,b), (2,a), (2,b))
A
B
D
E
G
F
C
look, Ma ...
wait 5 secs ...
... no threads!
^C$

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))

ScalaFp 02 (Choice)






Expect frequent changes.





Choice


Here is an of apect of computations: choice.


Here is ChoiceModule.
The abstract choice methods are _nothing and or.






package com.imaginej

package choice

trait ChoiceModule {
type M[+Z] <: Choice[Z]
def _nothing[Z]: M[Z]
trait Choice[+A] { self: M[A] =>
def or[B >: A](mb: => M[B]): M[B]
}
}




ChoiceMonads


The extra concrete choice monad method is withFilter.






package com.imaginej

package monad

package choice

import monad.MonadModule
import com.imaginej.choice.ChoiceModule

trait ChoiceMonadModule
extends MonadModule
with ChoiceModule {
type M[+Z] <: ChoiceMonad[Z]
trait ChoiceMonad[+A]
extends Monad[A]
with Choice[A] { self: M[A] =>
def withFilter(ap: A => Boolean) =
flatMap { a =>
if (ap(a)) {
_return(a)
} else {
_nothing
}
}
}
}




ChoiceMonad Instances


Here are some choice monad instances.







TraversableChoiceMonad.






package com.imaginej

package monad

package choice

package instances

import monad.choice.ChoiceMonadModule

object TraversableChoiceMonadObject
extends ChoiceMonadModule {
type M[+Z] = TraversableChoiceMonad[Z]
type In[-Z] = Unit
type Out[+Z] = Traversable[Z]
override def _return[Z] =
z => TraversableChoiceMonad(Traversable(z))
override def _nothing[Z] =
new TraversableChoiceMonad(Traversable())
def _close[Z]: Traversable[Z] => M[Z] =
TraversableChoiceMonad(_)
case class TraversableChoiceMonad[+A](val open: Traversable[A])
extends ChoiceMonad[A] {
override def run[B >: A](u: Unit): Traversable[B] =
this.open
override def flatMap[B](a_f_mb: A => M[B]): M[B] =
_close(for {
a <- this.open
b <- a_f_mb(a).open
} yield b)
override def or[B >: A](mb: => M[B]) =
_close(this.open ++ mb.open)
}
}





OptionChoiceMonad.




Note: options are not traversable, but we make them traversable
using an implicit conversion.






package com.imaginej

package monad

package choice

package instances

import monad.choice.ChoiceMonadModule

object OptionChoiceMonadObject
extends ChoiceMonadModule {
type M[+Z] = OptionChoiceMonad[Z]
type In[-Z] = Unit
type Out[+Z] = Option[Z]
override def _return[Z] =
z => OptionChoiceMonad(Some(z))
override def _nothing[Z] =
OptionChoiceMonad(None)
def _close[Z]: Option[Z] => M[Z] =
OptionChoiceMonad(_)
implicit def _ocm_f_tcm[Z]: M[Z] => TraversableChoiceMonadObject.M[Z] =
mz => TraversableChoiceMonadObject._close(mz.open)
case class OptionChoiceMonad[+A](val open: Option[A])
extends ChoiceMonad[A] {
override def run[B >: A](u: Unit): Option[B] =
this.open
override def flatMap[B](a_f_mb: A => M[B]): M[B] =
_close(for {
a <- this.open
b <- a_f_mb(a).open
} yield b)
override def or[B >: A](mb: => M[B]) =
_close(this.open orElse mb.open)
}
}




Implicit Choice Monads


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






import instances.TraversableChoiceMonadObject
import instances.OptionChoiceMonadObject

object ChoiceMonadModule {
implicit val traversableChoiceMonad =
TraversableChoiceMonadObject
implicit val optionChoiceMonad =
OptionChoiceMonadObject
}




Application


Here is an application.






package com.imaginej

package apps

import monad.choice.instances._

object UsingChoiceMonads {
def usingTraversableChoiceMonad() {
import TraversableChoiceMonadObject._
val computation =
for {
x <- _close(List(1, 2))
y <- _close(List(x + 1, x + 2))
if (x == y)
} yield (x, y)
println {
computation run ()
}
}
def usingOptionChoiceMonad() {
import OptionChoiceMonadObject._
val computation =
for {
x <- _close(Some(1))
y <- _close(Some(x + 1))
if (y >= 2)
} yield (x, y)
println {
computation run ()
}
}
def usingTwoChoiceMonads() {
import TraversableChoiceMonadObject.{ _close => _closeT, _ }
import OptionChoiceMonadObject.{ _close => _closeO, _ }
val maybeInts =
_closeT(List(_closeO(Some(1)), _closeO(None), _closeO(Some(2))))
val computation =
for {
maybeInt <- maybeInts
i <- maybeInt
if (i >= 2)
} yield i
println {
computation run ()
}
}
def main(args: Array[String]) {
usingTraversableChoiceMonad()
usingOptionChoiceMonad()
usingTwoChoiceMonads()
}
}





Running the application yields.




$ scala com.imaginej.apps.UsingChoiceMonads
List()
Some((1,2))
List(2)

Saturday, April 9, 2011

ScalaFp 01 (Monads)






Expect frequent changes.





Computations


The idea behind the ScalaFp library is to model aspects of computations in a functional way.


Here is ComputationModule.
The abtract computation method is run.
run is Computation functionality.


Note: Module scope type parameters are called Z, Y, X ... .


Note: Other type parameters are called A, B, C ... .








package com.imaginej

package computation

trait ComputationModule {
type M[+Z] <: Computation[Z]
type In[-Z]
type Out[+Z]
trait Computation[+A] { self: M[A] =>
def run[B >: A](i: In[B]): Out[B]
}
}




Monads


It is generally accepted that monads are convenient for modeling aspects of computations.
Here is MonadModule.
The abstract monad methods are _return and flatMap.
_return is MonadModule functionality.
flatMap is Monad functionality.


Note: Module functionality names will systematically start with an underscore.


The extra concrete monad methods are _join, >=, >> and map .






package com.imaginej

package monad

import computation.ComputationModule

trait MonadModule
extends ComputationModule {
type M[+Z] <: Monad[Z]
def _return[Z]: Z => M[Z]
def _join[Z]: M[M[Z]] => M[Z] =
_.flatMap(identity)
trait Monad[+A]
extends Computation[A] { self: M[A] =>
def flatMap[B](a_f_mb: A => M[B]): M[B]
def >=[B](a_f_mb: A => M[B]): M[B] =
flatMap(a_f_mb)
def >>[B](mb: => M[B]): M[B] =
this flatMap { _ => mb }
def map[B](afb: A => B) =
this flatMap (afb andThen _return)
}
}




Monad Instances


Here are some monad instances.







IdentityMonad.






package com.imaginej

package monad

package instances

import monad.MonadModule

object IdentityMonadObject
extends MonadModule {
type M[+Z] = IdentityMonad[Z]
type In[-Z] = Unit
type Out[+Z] = Z
override def _return[Z] =
IdentityMonad[Z](_)
def _close[Z]: Z => M[Z] =
IdentityMonad[Z](_)
case class IdentityMonad[+A](val open: A)
extends Monad[A] {
override def run[B >: A](u: Unit): B =
this.open
override def flatMap[B](a_f_mb: A => M[B]) =
a_f_mb(this.open)
}
}





TraversableMonad.






package com.imaginej

package monad

package instances

import monad.MonadModule

object TraversableMonadObject
extends MonadModule {
type M[+Z] = TraversableMonad[Z]
type In[-Z] = Unit
type Out[+Z] = Traversable[Z]
override def _return[Z] =
z => TraversableMonad(Traversable(z))
def _close[Z]: Traversable[Z] => M[Z] =
TraversableMonad(_)
case class TraversableMonad[+A](val open: Traversable[A])
extends Monad[A] {
override def run[B >: A](u: Unit): Traversable[B] =
this.open
override def flatMap[B](a_f_mb: A => M[B]) =
_close(
for {
a <- this.open
b <- a_f_mb(a).open
} yield b)
}
}





OptionMonad.




Note: options are not traversable, but we make them traversable
using an implicit conversion.






package com.imaginej

package monad

package instances

import monad.MonadModule

object OptionMonadObject
extends MonadModule {
type M[+Z] = OptionMonad[Z]
type In[-Z] = Unit
type Out[+Z] = Option[Z]
override def _return[Z] =
z => OptionMonad(Some(z))
def _close[Z]: Option[Z] => M[Z] =
OptionMonad(_)
implicit def _om_f_tm[Z]: M[Z] => TraversableMonadObject.M[Z] =
mz => TraversableMonadObject._close(mz.open)
case class OptionMonad[+A](val open: Option[A])
extends Monad[A] {
override def run[B >: A](u: Unit): Option[B] =
this.open
override def flatMap[B](a_f_mb: A => M[B]): M[B] =
_close(for {
a <- this.open
b <- a_f_mb(a).open
} yield b)
}
}




Implicit Monads


It is convenient to define implicit monads for later usage.






import instances.IdentityMonadObject
import instances.TraversableMonadObject
import instances.OptionMonadObject

object MonadModule {
implicit val identityMonad =
IdentityMonadObject
implicit val traversableMonad =
TraversableMonadObject
implicit val optionMonad =
OptionMonadObject
}




Application


Here is an application.






package com.imaginej

package apps

import monad.instances._

object UsingMonads {
def usingIdentityMonad() {
import IdentityMonadObject._
val computation =
for {
x <- _close(1)
y <- _close(x + 1)
} yield (x, y)
println {
computation run ()
}
}
def usingTraversableMonad() {
import TraversableMonadObject._
val computation1 =
for {
x <- _close(List(1, 2))
y <- _close(List(x + 1, x + 2))
} yield (x, y)
println {
computation1 run ()
}
val computation2 =
for {
x <- _close(List(1, 2))
y <- _close(List())
} yield (x, y)
println {
computation2 run ()
}
}
def usingOptionMonad() {
import OptionMonadObject._
val computation1 =
for {
x <- _close(Some(1))
y <- _close(Some(x + 1))
} yield (x, y)
println {
computation1 run ()
}
val computation2 =
for {
x <- _close(Some(1))
y <- _close(None)
} yield (x, y)
println {
computation2 run ()
}
}
def usingTwoMonads() {
import TraversableMonadObject.{ _close => _closeT, _ }
import OptionMonadObject.{ _close => _closeO, _ }
val maybeInts =
_closeT(List(_closeO(Some(1)), _closeO(None), _closeO(Some(2))))
val computation =
for {
maybeInt <- maybeInts
i <- maybeInt
} yield i
println {
computation run ()
}
}
def main(args: Array[String]) {
usingIdentityMonad()
usingTraversableMonad()
usingOptionMonad()
usingTwoMonads()
}
}





Running the application yields.




$ scala com.imaginej.apps.UsingMonads
(1,2)
List((1,2), (1,3), (2,3), (2,4))
List()
Some((1,2))
None
List(1, 2)

ScalaFp 00 (Logo)




This is the first of a series of blogs on a library, called ScalaFp, that I develop in my spare time.





Expect frequent changes.





Here is the ScalaFp logo.






____________________________________________________________________________________
/ ___ _________ /\
/ / /\ / ______/\ / /
/ _________ _________ _________ / / /_________ / /\_____\/________ / /
/ / ______/\ / ______/\ /_____ /\ / / //_____ /\ / /_/__ / ___ /\ / /
/ / /_____ \// /\_____\/_\____/ / // / /_\____/ / / / ____/\ / /__/ / / / /
/ /_____ /\ / / / / ___ / // / // ___ / / / /\____\/ / _____/ / / /
/ _______/ / // /_/___ / /__/ / // / // /__/ / / / / / / /\____\/ / /
/ /________/ //________/\ /________/ //__/ //________/ / /__/ / /__/ / / /
/ \________\/ \________\/ \________\/ \__\/ \________\/ \__\/ \__\/ v1.0 / /
/ / /
/ Scala Functional Programming Library / /
/ author Luc Duponcheel 2009-2011 / /
/___________________________________________________________________________________/ /
\___________________________________________________________________________________\/