Skip to content

Instantly share code, notes, and snippets.

View dsugden's full-sized avatar

Dave Sugden dsugden

  • Shopify
  • Gatineau
View GitHub Profile
@dsugden
dsugden / gist:9155772
Last active August 29, 2015 13:56
More interesting OO State
case class Node(id:Int)
type SyncResponse = Either[String,List[Node]]
class Network {
var nodes: ListBuffer[Node] = ListBuffer.empty
val rng = scala.util.Random
/**
* Removes dead nodes
*/
def purge:SyncResponse = {
@dsugden
dsugden / FooState
Created February 22, 2014 14:05
OO state
class Foo{
private var fooState = 0
def next:Int = { fooState = fooState + 1; fooState }
def getFooState:Int = fooState
}
val foo = new Foo()
foo.next
foo.next
val result = foo.next
@dsugden
dsugden / StateTLearning.scala
Last active August 29, 2015 13:57
StateT with Option and Either
import scalaz._
import Scalaz._
object StateTLearning extends App with StateTFunctions {
case class DB(v: Int)
val initial = DB(1)
def sum(i:Int) = StateChange[Better,Int](s => Better.sum(i)(s))
// Lets run the sum computation, and add all the results together
def composeAddResultS(one:Int,two:Int,three:Int): StateChange[Better,Int] =
sum(one).doAgainWithNewState(
firstResult =>
sum(two).doAgainWithNewState( secondResult =>
sum(three).mapResult( thirdResult => firstResult + secondResult + thirdResult) ))
object UseScalaz {
def main(args: Array[String]): Unit = {
import scalaz._
case class Better(total: List[Int])
// we notice S => (S,A) is useful, almost composable and testable, but awkward... lets do better
// Lets create a type that wraps the computation, and add some useful combinators: mapResult, doAgainWithResultAndNewState
case class StateChange[S,A](run: S => (S,A)){
def mapResult[B](f:A => B):StateChange[S,B] = StateChange{ (s:S) =>
val(s2,a) = run(s)
(s2,f(a))
}
/*
// we desire this pattern Better => (Better,Int)
type BetterUpdate = Better => (Better,Int)
val firstF:BetterUpdate = Better.sum(1)
val secondF:BetterUpdate = Better.sum(2)
val thirdF:BetterUpdate = Better.sum(3)
// the external state is threaded through a sequence of computations
case class Better(total : List[Int])
object Better{
def sum(i:Int)(b:Better):(Better,Int) = {
val result = if(b.total.length > 1) 99 else b.total.sum
val newBetter = b.copy(total = i :: b.total)
(newBetter, result)
}
@dsugden
dsugden / TraditionalMutation.scala
Last active August 29, 2015 14:02
A traditional OO mutation code example showing methods that hide side effects
class TraditionalMutation{
var total : List[Int] = Nil // Mutable List
/*
Add i to total, return it's sum
This method hides the effect of updating total
*/
def sum(i:Int):Int = {
total = i :: total // SIDE EFFECT
@dsugden
dsugden / MutableBad.scala
Last active August 29, 2015 14:02
Example of dangers of mutation
object MutableBad{
class MDate(dayIn:Int){ var day = dayIn }
type Task = Int
def scheduleTask(task:Task,date:MDate) = ???
var d = new MDate(22)