Skip to content

Commit 766a433

Browse files
Using Thoughtwork's Each to implement Interaction in InteractorExample.
Created example for Each-issue ThoughtWorksInc/sde#41
1 parent 91a5d50 commit 766a433

File tree

7 files changed

+68
-231
lines changed

7 files changed

+68
-231
lines changed

src/TempMacro.scala

Lines changed: 0 additions & 125 deletions
This file was deleted.

src/trafo/Interaction.scala

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package trafo
22
import scala.language.existentials
33
import cmathml.{CMathML, CNone, Path}
4+
import com.thoughtworks.each.Monadic
45
import misc.Pure
56
import theory.Formula
67

@@ -11,6 +12,7 @@ import scala.util.control.Breaks
1112
import scala.runtime.BoxedUnit
1213
import scala.xml.Elem
1314
import scala.reflect.runtime.universe._
15+
import scalaz.Monad
1416

1517

1618
abstract class Question[T] {
@@ -94,12 +96,12 @@ final case class InteractionFinished[T](result: T) extends Interaction[T] {
9496
override def withFilter(p: (T) => Boolean): Interaction[T] =
9597
if (p(result)) this else InteractionFailed()
9698
}
97-
final case class InteractionFailed[T]() extends Interaction[T] {
98-
override def resultMaybe: Option[T] = None
99+
final case class InteractionFailed() extends Interaction[Nothing] {
100+
override def resultMaybe: Option[Nothing] = None
99101
override def isDone: Boolean = false
100102
override def isRunning: Boolean = false
101103
override def isFailed: Boolean = true
102-
override def withFilter(p: (T) => Boolean): Interaction[T] = this
104+
override def withFilter(p: Nothing => Boolean) = this
103105
}
104106

105107
sealed trait Interaction[+T] {
@@ -152,7 +154,8 @@ sealed trait Interaction[+T] {
152154
}
153155

154156
object Interaction {
155-
def fail[T] = new InteractionFailed[T]()
157+
def fail = new InteractionFailed()
158+
def failU : Interaction[Unit] = fail
156159
def returnval[T](res : T) = new InteractionFinished[T](res)
157160
def ask[T<:AnyRef](id : String, question : Question[T]) =
158161
new InteractionRunning[T](id,question, { a =>
@@ -162,7 +165,16 @@ object Interaction {
162165
})
163166
def error(id:String,err:Elem) : Interaction[Unit] =
164167
new InteractionRunning[Unit](id,MessageQ.Error(err),{a=>returnval(())})
165-
def failWith[T](id:String, err:Elem) : Interaction[T] =
166-
for { _ <- error(id, err); res <- fail[T] } yield res
168+
def failWith(id:String, err:Elem) : Interaction[Nothing] =
169+
for { _ <- error(id, err); res <- fail } yield res
170+
def failWithU(id:String, err:Elem) : Interaction[Unit] = failWith(id,err)
167171
val skip : Interaction[Unit] = returnval(())
172+
173+
implicit object interactionInstance extends Monad[Interaction] {
174+
override def bind[A, B](fa: Interaction[A])(f: (A) => Interaction[B]): Interaction[B] = fa.flatMap(f)
175+
override def point[A](a: => A): Interaction[A] = returnval(a)
176+
}
177+
178+
val interaction = Monadic.monadic[Interaction]
168179
}
180+

src/ui/Interactor.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ object Interactor {
221221
case _:NumberFormatException => /*valueProperty.setValue(None)*/ ()
222222
})
223223
valueProperty.addListener({ (newVal:Integer) =>
224-
println("change: ",newVal)
224+
Log.debug("change: ",newVal)
225225
textProperty.setValue(newVal.toString)})
226226
}
227227

test/Temp.scala

Lines changed: 0 additions & 85 deletions
This file was deleted.

test/trafo/InteractionTest.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ class InteractionTest extends UnitSpec {
4545
}
4646

4747
test("fail in for (last step)") {
48-
val int : Interaction[Integer] = for { i <- Interaction.fail[Integer] } yield i
48+
val int : Interaction[Integer] = for { i <- Interaction.fail } yield i
4949
assert(isFailed(int))
5050
}
5151

5252
test("fail in for (prev step)") {
53-
val int = for { i <- Interaction.fail[String]; j <- returnval(3 : Integer) } yield j
53+
val int = for { i <- Interaction.fail; j <- returnval(3 : Integer) } yield j
5454
assert(isFailed(int))
5555
}
5656

test/tryouts/MonadicNeedsCast.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import scalaz._
2+
import Scalaz._
3+
import com.thoughtworks.each.Monadic._
4+
5+
object MonadicNeedsCast {
6+
def main(args: Array[String]): Unit = {
7+
val monad = monadic[Option] {
8+
None.each // Normally, this would be inside an if and represent a failure of the computation
9+
// (None:Option[Unit]).each // This one works
10+
55
11+
}
12+
println(monad) // Should be None
13+
}
14+
}

test/ui/InteractorExample.scala

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,56 @@
11
package ui
22

3+
import scalaz._
4+
import Scalaz._
35
import javafx.animation.{KeyFrame, Timeline}
46
import javafx.event.ActionEvent
57
import javafx.util
68

9+
import com.thoughtworks.each.Monadic._
10+
import misc.Log
711
import misc.Utils.ImplicitConversions._
812
import trafo.Interaction._
913
import trafo.{IntQ, Interaction, StringQ}
1014

15+
import scala.language.postfixOps
16+
1117
object InteractorExample {
18+
// implicit object interactionInstance extends Monad[Interaction] {
19+
// override def bind[A, B](fa: Interaction[A])(f: (A) => Interaction[B]): Interaction[B] = fa.flatMap(f)
20+
// override def point[A](a: => A): Interaction[A] = returnval(a)
21+
// }
22+
// implicit object seqTraverse extends Traverse[Seq] {
23+
// override def traverseImpl[F[_], A, B](l: Seq[A])(f: (A) => F[B])(implicit applicative: Applicative[F]): F[Seq[B]] =
24+
// listInstance.traverseImpl(l.toList)(f)
25+
// }
26+
// listInstance
27+
// MonadPlus[Interactor] /* with IsEmpty[Interactor] */ =
28+
29+
1230
def main(args: Array[String]) = {
1331
TestFxApp.run {
14-
def manyQ(i:Int, j:Int=1) : Interaction[List[String]] = i match {
15-
case 0 => returnval(List.empty)
16-
case _ if i >= 0 =>
17-
for {x <- ask("i" + j, new StringQ(<span>String nr. <b>{j}</b></span>))
18-
xs <- manyQ(i - 1, j + 1)
19-
} yield x :: xs
32+
val int = interaction {
33+
val i : Int = ask("int", new IntQ(<span>Nr 1?</span>)).each
34+
if (i>10) failWithU("i>10", <span>i must be at most 10</span>).each
35+
val strs = for (j <- (1 to i).toList.monadicLoop) yield
36+
ask("i" + j, new StringQ(<span>String nr. <b>{j}</b></span>)).each
37+
38+
if (strs.contains("")) failU.each
39+
""+i+"#"+strs.mkString(",")
2040
}
2141

22-
val int = for {i <- ask("int", new IntQ(<span>Nr 1?</span>))
23-
strs <- manyQ(i)
24-
_ <- if (strs.contains("")) fail else returnval(())
25-
} yield ""+i+"#"+strs.mkString(",")
42+
val xxx = monadic[List] {
43+
val i = (Nil:List[Unit]).each
44+
55
45+
}
2646

2747
val actor = new Interactor(int)
2848
// actor.setAnswer(0,"hello")
49+
Log.info("initial result",actor.result)
2950

30-
actor.setAnswer(0,-1.asInstanceOf[Integer])
51+
actor.result.onChange { (_,_,res) => Log.info("result",res) }
3152

32-
actor.result.onChange { (_,_,res) => println(res) }
53+
actor.setAnswer(0,-1.asInstanceOf[Integer])
3354

3455
val timeline = new Timeline(
3556
new KeyFrame(util.Duration.millis(1000), {(_:ActionEvent) => actor.setAnswer(0,1.asInstanceOf[Integer])}),

0 commit comments

Comments
 (0)