Skip to content

Instantly share code, notes, and snippets.

View kenbot's full-sized avatar

Ken Scambler kenbot

  • Melbourne, Australia
View GitHub Profile
@kenbot
kenbot / coyo.scala
Created May 1, 2017 03:49
Example of Coyoneda use with free monads in Scala
import scalaz._, Scalaz._
// Model
case class UserId(id: String)
case class RequestId(id: String)
case class Message(body: String)
trait Authenticator { def authenticate(token: String): Option[UserId] }
trait MessageDb {
def getMessageList(id: String): List[String]
def addMessage(id: String, body: String): Unit
import scala.math.Ordering
sealed trait Interval[A] {
def intersect(that: Interval[A])(implicit order: Ordering[A]): Interval[A] = (this, that) match {
case (Nonempty(s1, e1), Nonempty(s2, e2)) if (order.gteq(e2,s1)) && (order.gteq(e1,s2)) =>
val start = order.max(s1, s2)
val end = order.min(e1, e2)
Nonempty(start, end)
case _ => Empty()
}
@kenbot
kenbot / Classes.scala
Created May 15, 2015 03:30
Example code for Lambda Jam Category Theory exercises
package cat
object Classes {
// Convenient subtype syntax: Banana < Fruit
implicit class ClassOps(thisClass: Class[_]) {
def <:<(other: Class[_]): Boolean =
other isAssignableFrom thisClass
}
@kenbot
kenbot / Exercise1.scala
Created May 15, 2015 03:29
Sketch of first Category Theory exercise for Lambda Jam.
package kenbot.yowcat
/**
* Lets start with this representation of a category.
*
* Ordinarily we'd make better use of the type system here,
* but we want to manipulate all these concepts at the value level.
*
* Throughout, we'll use scala.Stream to represent sets or collections in the mathematical sense, even though they don't guarantee uniqueness.
@kenbot
kenbot / Hose.scala
Last active November 25, 2015 15:51
Garden Hoses as a Category in Scala
// Category
//
trait Category[Arrow[_,_]] {
def compose[A,B,C](c1: Arrow[B,C], c2: Arrow[A,B]): Arrow[A,C]
def id[A]: Arrow[A,A]
}
object Category {
implicit object FunctionCat extends Category[Function1] {
def compose[A,B,C](f: B => C, g: A => B): A => C = f compose g
@kenbot
kenbot / ScalaReaderSugar.scala
Created October 3, 2014 15:57
Syntax sugar to effortlessly interoperate between Reader monads
case class has[Owner, A](get: Owner => A)
implicit def ownerHasPairs[Owner, A, B](implicit a: Owner has A, b: Owner has B): Owner has (A,B) =
has(owner => (a.get(owner), b.get(owner)))
implicit def pairHas1st[A,B]: (A,B) has A = has(_._1)
implicit def pairHas2nd[A,B]: (A,B) has B = has(_._2)
implicit def widenReaderToOwner[Owner, O, A](reader: Reader[O, A])(implicit ev: Owner has O): Reader[Owner, A] =
reader.local[Owner](implicitly[Owner has O].get)
package fpexample
import scala.util.Try
import scala.io.Source
case class Record[K,+A](key: K, fields: A) {
def map[B](f: A => B): Record[K, B] = Record(key, f(fields))
}
object DataMunger {
@kenbot
kenbot / ListReverser
Created June 18, 2014 15:17
List reverse implementation
package fpexample
object ListReverser {
// I don't see how this can be done in anything less than linear time
// (ie proportional to the length of the list).
//
// Space usage shouldn't vary, since foldLeft is tail recursive,
// and the size of the accumulated list grows at the same rate
@kenbot
kenbot / gist:7c0683e347f0a871f559
Created May 6, 2014 00:53
Binary tree generation
// Can it really be this hard???
sealed trait BinTree
case class Node(left: BinTree, right: BinTree) extends BinTree
case class Leaf(n: Int) extends BinTree
def generateTree(ints: Iterable[Int]): BinTree = {
type BinTreePair = (BinTree, BinTree)
def pairOffTrees(trees: List[BinTree]): List[BinTreePair] = {
@kenbot
kenbot / swingworkerdsl.scala
Created January 30, 2013 13:42
Simple DIY Scala DSL for javax.swing.SwingWorker
object Async {
def async[A](thunk: => A)(whenDone: A => Unit) {
val swingWorker = new javax.swing.SwingWorker[A, Any] {
override def doInBackground(): A = thunk
override def done(): Unit = whenDone(get)
}
swingWorker.execute()
}
}