scala> type Stack = List[Int]
defined type alias Stack
scala> defpop(stack: Stack): (Int, Stack) = stack match {
case x :: xs => (x, xs)
}
pop: (stack: Stack)(Int, Stack)
scala> defpush(a: Int, stack: Stack): (Unit, Stack) = ((), a :: stack)
push: (a: Int, stack: Stack)(Unit, Stack)
scala> defstackManip(stack: Stack): (Int, Stack) = {
val (_, newStack1) = push(3, stack)
val (a, newStack2) = pop(newStack1)
pop(newStack2)
}
stackManip: (stack: Stack)(Int, Stack)
scala> stackManip(List(5, 8, 2, 1))
res0: (Int, Stack) = (5,List(8, 2, 1))
We’ll say that a stateful computation is a function that takes some
state and returns a value along with some new state.
That function would have the following type:s -> (a, s)
type State[S, +A] = StateT[Id, S, A]
// important to define here, rather than at the top-level, to avoid Scala 2.9.2 bugobjectStateextendsStateFunctions {def apply[S, A](f: S => (S, A)): State[S, A] = new StateT[Id, S, A] {
def apply(s: S) = f(s)
}
}
traitStateT[F[+_], S, +A] { self =>
/** Run and return the final value and state in the context of `F` */def apply(initial: S): F[(S, A)]
/** An alias for `apply` */def run(initial: S): F[(S, A)] = apply(initial)
/** Calls `run` using `Monoid[S].zero` as the initial state */def runZero(implicit S: Monoid[S]): F[(S, A)] =
run(S.zero)
}
scala> defstackyStack: State[Stack, Unit] = for {
stackNow <- get
r <- if (stackNow === List(1, 2, 3)) put(List(8, 3, 1))
else put(List(9, 2, 1))
} yield r
stackyStack: scalaz.State[Stack,Unit]
scala> stackyStack(List(1, 2, 3))
res4: (Stack, Unit) = (List(8, 3, 1),())
// We can also implement pop and push in terms of get and put:
scala> val pop: State[Stack, Int] = for {
s <- get[Stack]
val (x :: xs) = s
_ <- put(xs)
} yield x
pop: scalaz.State[Stack,Int] = scalaz.StateT$$anon$7@40014da3
scala> defpush(x: Int): State[Stack, Unit] = for {
xs <- get[Stack]
r <- put(x :: xs)
} yield r
push: (x: Int)scalaz.State[Stack,Unit]
Either
We know Either[A, B] from the standard library, but Scalaz 7
implements its own Either equivalent named \/:
sealedtrait \/[+A, +B] {
...
/** Return `true` if this disjunction is left. */def isLeft: Boolean =
thismatch {
case -\/(_) => truecase \/-(_) => false
}
/** Return `true` if this disjunction is right. */def isRight: Boolean =
thismatch {
case -\/(_) => falsecase \/-(_) => true
}
...
/** Flip the left/right values in this disjunction. Alias for `unary_~` */def swap: (B \/ A) =
thismatch {
case -\/(a) => \/-(a)
case \/-(b) => -\/(b)
}
/** Flip the left/right values in this disjunction. Alias for `swap` */def unary_~ : (B \/ A) = swap
...
/** Return the right value of this disjunction or the given default if left. Alias for `|` */def getOrElse[BB >: B](x: => BB): BB =
toOption getOrElse x
/** Return the right value of this disjunction or the given default if left. Alias for `getOrElse` */def |[BB >: B](x: => BB): BB = getOrElse(x)
/** Return this if it is a right, otherwise, return the given value. Alias for `|||` */def orElse[AA >: A, BB >: B](x: => AA \/ BB): AA \/ BB =
thismatch {
case -\/(_) => x
case \/-(_) => this
}
/** Return this if it is a right, otherwise, return the given value. Alias for `orElse` */def |||[AA >: A, BB >: B](x: => AA \/ BB): AA \/ BB = orElse(x)
...
}
privatecaseclass -\/[+A](a: A)extends(A \/ Nothing)privatecaseclass \/-[+B](b: B)extends(Nothing \/ B)
/** A singly-linked list that is guaranteed to be non-empty. */sealedtraitNonEmptyList[+A] {val head: A
val tail: List[A]
def <::[AA >: A](b: AA): NonEmptyList[AA] = nel(b, head :: tail)
...
}
This is a wrapper trait for plain List that’s guaranteed to be non-empty.
As a bonus, Scalaz defines Reader as a special case of Kleisli as follows:
1
2
3
4
5
type ReaderT[F[+_], E, A] = Kleisli[F, E, A]
type Reader[E, A] = ReaderT[Id, E, A]
object Reader {
def apply[E, A](f: E => A): Reader[E, A] = Kleisli[Id, E, A](f)
}
1
2
3
4
5
6
7
8
scala> val addStuff: Reader[Int, Int] = for {
a <- Reader { (_: Int) * 2 }
b <- Reader { (_: Int) + 10 }
} yield a + b
addStuff: scalaz.Reader[Int,Int] = scalaz.KleisliFunctions$$anon$18@343bd3ae
scala> addStuff(3)
res76: scalaz.Id.Id[Int] = 19
Making monads
What if we wanted to model a non-deterministic value like [3,5,9]
but we wanted to express that 3 has a 50% chance of happening and 5 and 9
both have a 25% chance of happening?
caseclassProb[A](list: List[(A, Double)])// the list is a functor, so this should probably be a functor as well,// because we just added some stuff to the list.traitProbInstances {def flatten[B](xs: Prob[Prob[B]]): Prob[B] = {
def multall(innerxs: Prob[B], p: Double) =
innerxs.list map { case (x, r) => (x, p * r) }
Prob((xs.list map { case (innerxs, p) => multall(innerxs, p) }).flatten)
}
implicit val probInstance = new Functor[Prob] {
def map[A, B](fa: Prob[A])(f: A => B): Prob[B] =
Prob(fa.list map { case (x, p) => (f(x), p) })
}
implicit def probShow[A]: Show[Prob[A]] = Show.showA
}
caseobjectProbextendsProbInstances
The probability of having all three coins on Tails even
with a loaded coin is pretty low.
1
2
3
4
5
6
7
8
9
10
11
12
13
sealedtraitCoincaseobjectHeadsextendsCoincaseobjectTailsextendsCoin
implicit val coinEqual: Equal[Coin] = Equal.equalA
def coin: Prob[Coin] = Prob(Heads -> 0.5 :: Tails -> 0.5 :: Nil)
def loadedCoin: Prob[Coin] = Prob(Heads -> 0.1 :: Tails -> 0.9 :: Nil)
def flipThree: Prob[Boolean] = for {
a <- coin
b <- coin
c <- loadedCoin
} yield { List(a, b, c) all {_ === Tails} }
sealedtraitTreeLoc[A] {import TreeLoc._
import Tree._
/** The currently selected node. */val tree: Tree[A]
/** The left siblings of the current node. */val lefts: TreeForest[A]
/** The right siblings of the current node. */val rights: TreeForest[A]
/** The parent contexts of the current node. */val parents: Parents[A]
...
}
objectTreeLocextendsTreeLocFunctionswithTreeLocInstances {def apply[A](t: Tree[A], l: TreeForest[A], r: TreeForest[A], p: Parents[A]): TreeLoc[A] =
loc(t, l, r, p)
}
traitTreeLocFunctions {type TreeForest[A] = Stream[Tree[A]]
type Parent[A] = (TreeForest[A], A, TreeForest[A])
type Parents[A] = Stream[Parent[A]]
}
// similar to DOM API:sealedtraitTreeLoc[A] {
...
/** Select the parent of the current node. */def parent: Option[TreeLoc[A]] = ...
/** Select the root node of the tree. */def root: TreeLoc[A] = ...
/** Select the left sibling of the current node. */def left: Option[TreeLoc[A]] = ...
/** Select the right sibling of the current node. */def right: Option[TreeLoc[A]] = ...
/** Select the leftmost child of the current node. */def firstChild: Option[TreeLoc[A]] = ...
/** Select the rightmost child of the current node. */def lastChild: Option[TreeLoc[A]] = ...
/** Select the nth child of the current node. */def getChild(n: Int): Option[TreeLoc[A]] = ...
/** Select the first immediate child of the current node that satisfies the given predicate. */def findChild(p: Tree[A] => Boolean): Option[TreeLoc[A]] = ...
/** Get the label of the current node. */def getLabel: A = ...
/** Modify the current node with the given function. */def modifyTree(f: Tree[A] => Tree[A]): TreeLoc[A] = ...
/** Modify the label at the current node with the given function. */def modifyLabel(f: A => A): TreeLoc[A] = ...
/** Insert the given node as the last child of the current node and give it focus. */def insertDownLast(t: Tree[A]): TreeLoc[A] = ...
...
}
/** The strict identity type constructor. Can be thought of as `Tuple1`, but with no
* runtime representation.
*/
type Id[+X] = X
trait IdOps[A] extends Ops[A] {
/**Returns `self` if it is non-null, otherwise returns `d`. */
final def ??(d: => A)(implicit ev: Null <:< A): A =
if (self == null) d else self
/**Applies `self` to the provided function */
final def |>[B](f: A => B): B = f(self)
final defsquared: (A, A) = (self, self)
defleft[B]: (A \/ B) = \/.left(self)
defright[B]: (B \/ A) = \/.right(self)
final defwrapNel: NonEmptyList[A] = NonEmptyList(self)
/** @return the result of pf(value) if defined, otherwise the the Zero element of type B. */defmatchOrZero[B: Monoid](pf: PartialFunction[A, B]): B = ...
/** Repeatedly apply `f`, seeded with `self`, checking after each iteration whether the predicate `p` holds. */
final defdoWhile(f: A => A, p: A => Boolean): A = ...
/** Repeatedly apply `f`, seeded with `self`, checking before each iteration whether the predicate `p` holds. */
final defwhileDo(f: A => A, p: A => Boolean): A = ...
/** If the provided partial function is defined for `self` run this,
* otherwise lift `self` into `F` with the provided [[scalaz.Pointed]]. */
defvisit[F[_] : Pointed](p: PartialFunction[A, F[A]]): F[A] = ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// |> lets you write the function application at the end of an expression:
scala> 1 + 2 + 3 |> {_.point[List]}
res45: List[Int] = List(6)
scala> 1 + 2 + 3 |> {_ * 6}
res46: Int = 36// visit is also kind of interesting:
scala> 1 visit { case x@(2|3) => List(x * 2) }
res55: List[Int] = List(1)
scala> 2 visit { case x@(2|3) => List(x * 2) }
res56: List[Int] = List(4)
Lawless typeclasses
Scalaz 7.0 contains several typeclasses that are now deemed
lawless by Scalaz project: Length, Index, and Each.
Length
1
2
3
trait Length[F[_]] { self =>
deflength[A](fa: F[A]): Int
}
scala> case class Turtle(position: Point, heading: Double, color: Color) {
def forward(dist: Double): Turtle =
copy(position =
position.copy(
x = position.x + dist * math.cos(heading),
y = position.y + dist * math.sin(heading)
))
}
defined class Turtle
scala> Turtle(Point(2.0, 3.0), 0.0,
Color(255.toByte, 255.toByte, 255.toByte))
res10: Turtle = Turtle(Point(2.0,3.0),0.0,Color(-1,-1,-1))
scala> res10.forward(10)
res11: Turtle = Turtle(Point(12.0,3.0),0.0,Color(-1,-1,-1))
// To update the child data structure, we need to nest copy call.
// To quote from Seth’s example again:
// imperative
a.b.c.d.e += 1
// functional
a.copy(
b = a.b.copy(
c = a.b.c.copy(
d = a.b.c.d.copy(
e = a.b.c.d.e + 1
))))
sealedtraitLensT[F[+_], A, B] {def get(a: A)(implicit F: Functor[F]): F[B] =
F.map(run(a))(_.pos)
def set(a: A, b: B)(implicit F: Functor[F]): F[A] =
F.map(run(a))(_.put(b))
/** Modify the value viewed through the lens */def mod(f: B => B, a: A)(implicit F: Functor[F]): F[A] = ...
def =>=(f: B => B)(implicit F: Functor[F]): A => F[A] =
mod(f, _)
/** Modify the portion of the state viewed through the lens and return its new value. */def %=(f: B => B)(implicit F: Functor[F]): StateT[F, A, B] =
mods(f)
/** Lenses can be composed */def compose[C](that: LensT[F, C, A])(implicit F: Bind[F]): LensT[F, C, B] = ...
/** alias for `compose` */def <=<[C](that: LensT[F, C, A])(implicit F: Bind[F]): LensT[F, C, B] = compose(that)
def andThen[C](that: LensT[F, B, C])(implicit F: Bind[F]): LensT[F, A, C] =
that compose this/** alias for `andThen` */def >=>[C](that: LensT[F, B, C])(implicit F: Bind[F]): LensT[F, A, C] = andThen(that)
}
Lens laws
1
2
3
4
5
6
7
8
9
10
11
12
trait LensLaw {
def identity(a: A)(implicit A: Equal[A], ev: F[Store[B, A]] =:= Id[Store[B, A]]): Boolean = {
val c = run(a)
A.equal(c.put(c.pos), a)
}
def retention(a: A, b: B)(implicit B: Equal[B], ev: F[Store[B, A]] =:= Id[Store[B, A]]): Boolean =
B.equal(run(run(a) put b).pos, b)
def doubleSet(a: A, b1: B, b2: B)(implicit A: Equal[A], ev: F[Store[B, A]] =:= Id[Store[B, A]]) = {
val r = run(a)
A.equal(run(r put b1) put b2, r put b2)
}
}