Skip to content

Instantly share code, notes, and snippets.

@chrislewis
chrislewis / gist:1020656
Created June 11, 2011 15:18
functor for java.util.concurrent.Future
/*
* Functor instance for Future to accumulate transformations
* to be called only when Future#get is invoked.
*/
implicit def FutureFunctor = new Functor[Future] {
def fmap[A, B](r: Future[A], f: A => B) = new Future[B] {
def cancel(miir: Boolean) = r.cancel(miir)
def isCancelled() = r.isCancelled()
def isDone() = r.isDone()
@chrislewis
chrislewis / gist:1002295
Created June 1, 2011 13:32
a fledgling Exception monad based on a partially applied Either
trait Monad[M[_]] {
def unit[A](a: A): M[A]
def bind[A, B](ma: M[A], f: A => M[B]): M[B]
}
val ExceptionM = new Monad[({type Ex[A]=Either[Exception, A]})#Ex] {
def unit[A](a: A): Either[Exception, A] = Right(a)
def bind[A, B](ma: Either[Exception, A], f: A => Either[Exception, B]) =
ma match {
case Left(e) => Left(e)
def feab[E, A, B](fab: A => Either[E, B], fea: E => Either[E, A])(a: A): Either[E, B] =
fab(a) fold(fea(_) fold (Left(_), fab), Right(_))
trait TransactionService {
def create(user: User, item: Item): Result[AlreadyPurchasedEx, Transaction]
}
trait PaymentService {
def buy(user: User, howMany: Int): Result[PaymentFailedEx, Int]
}
trait CreditService {
def expend(p: (User, Int)): Result[NotEnoughFundsEx, Int]
trait TransactionService {
/*
* Create a record of user purchase.
* throws AlreadyPurchasedEx
*/
def create(user: User, item: Item): Transaction
}
trait PaymentService {
/*
class BasicPurchaseService(
val txs: TransactionService,
val credits: CreditService,
val payments: PaymentService,
val log: Log
) extends PurchaseService {
def purchase(user: User, item: Item) =
try {
if(! credits.canAfford(user, item.cost))
class BasicPurchaseService(
val txs: TransactionService,
val credits: CreditService,
val payments: PaymentService,
val log: PurchaseEx => Result[PurchaseEx, Receipt]
) extends PurchaseService {
val buy = credits.ensure(payments.buy)_
def prchs(user: User, item: Item) = for {
@chrislewis
chrislewis / Result.scala
Created April 4, 2011 00:21
sketch of a monadic disjoint union (like Either, but a monad)
sealed trait Result[+F, S] {
def flatMap[FF >: F, SS](f: S => Result[FF, SS]): Result[FF, SS]
def map[SS](f: S => SS): Result[F, SS]
def fold[X](ff: F => X, fs: S => X): X
}
case class Failure[+F, S](x: F) extends Result[F, S] {
def flatMap[FF >: F, SS](f: S => Result[FF, SS]) = Failure[FF, SS](x)
def map[SS](f: S => SS) = Failure[F, SS](x)
def fold[X](ff: F => X, fs: S => X) = ff(x)
class RichEither[L, R](val either: Either[L, R]) {
def map[RR](f: R => RR): Either[L, RR] = either match {
case Left(l) => Left(l)
case Right(r) => Right(f(r))
}
def flatMap[RR](f: R => Either[L, RR]): Either[L, RR] = either match {
case Left(l) => Left(l)
case Right(r) => f(r)
}
@chrislewis
chrislewis / taming_either.scala
Created February 28, 2011 04:38
taming Either
class RichEither[L, R](val either: Either[L, R]) {
def mapRight[RR](f: R => RR): Either[L, RR] = either match {
case Left(l) => Left(l)
case Right(r) => Right(f(r))
}
}
implicit def either2rich[L, R](either: Either[L, R]) = new RichEither(either)
/*