Skip to content

Instantly share code, notes, and snippets.

View tpolecat's full-sized avatar
🔥
Dijkstra would not have liked this.

Rob Norris tpolecat

🔥
Dijkstra would not have liked this.
View GitHub Profile

doobie experiment - postgres NOTIFY as scalaz-stream

One of the cool things PostgreSQL gives you is a simple notification system that you can use to let clients know that something interesting has happened. For instance you can set up rules that broadcast notifications when a table is updated, and client applications can update displays in response. The JDBC driver provides access to this API so I thought I would see what it would look like in doobie.

The program below constructs a Process[ConnectionIO, PGNotification] that registers for events, polls for them periodically (this is the best we can do with current driver support), and unregisters when the stream terminates for any reason. We use a Transactor to replace ConnectionIO with Task which gives us something we can actually run.

package doobie.example

import doobie.imports._
def mergeRanges(ns: List[Int]): List[Range] =
ns.foldRight(List.empty[Range]) {
case (n, r :: rs) if (n == r.min - 1) => (n to r.max) :: rs
case (n, rs) => (n to n) :: rs
}
import scalaz.{ Free, Coyoneda, Monad, ~>, State, NonEmptyList }
import scalaz.std.function._
import scalaz.syntax.monad._
import scalaz.effect.IO
import scala.util.Random
object freecoyo extends App {
// An algebra of primitive operations in the context of a random number generator

Hi, looking for scalac flags?

This gist has been upgraded to a blog post here.

implicit def treeEncode[A: EncodeJson]: EncodeJson[Tree[A]] =
EncodeJson(t => (t.rootLabel, t.subForest).asJson)
implicit def treeDecode[A: DecodeJson]: DecodeJson[Tree[A]] =
DecodeJson(c =>
for {
rootLabel <- (c =\ 0).as[A]
subForest <- (c =\ 1).as[Stream[Tree[A]]]
} yield Tree.node(rootLabel, subForest)
> runMain doobie.hi.Test
[info] Compiling 37 Scala sources to /Users/rnorris/Scala/doobie/target/scala-2.10/classes...
[info] Running doobie.hi.Test
The answer was: java.lang.RuntimeException: Bogus country: NCL
nyQL log for hi.examples
+- [ok] getConnection(jdbc:h2:mem:test;DB_CLOSE_DELAY=-1, sa, ***) | conn1: url=jdbc:h2:mem:test us 304.109 ms
`- [ex] database session | Bogus country: NCL 1496.911 ms
+- [ok] populate database from /Users/rnorris/Scala/doobie/world.sql | false 1378.663 ms
| +- [ok] prepareStatement(RUNSCRIPT FROM ? CHARSET 'UTF-8') | prep1: RUNSCRIPT FROM ? CHARSE 3.950 ms
scala> class Foo(val n: Int)
defined class Foo
scala> class Bar(n: Int) extends Foo(n)
defined class Bar
scala> List[Foo]().sorted
<console>:9: error: No implicit Ordering defined for Foo.
List[Foo]().sorted
^
@tpolecat
tpolecat / infset.scala
Created December 22, 2013 17:29 — forked from non/infset.scala
package spire.examples
import spire.algebra._
import spire.math.{Natural, UInt}
import scala.collection.mutable
object SetUtil {
def powerStream[A](members: Stream[A]): Stream[Set[A]] = {
val done = Stream.empty[Set[A]]
@tpolecat
tpolecat / gist:7554206
Last active December 28, 2015 19:59
Having a bit of a problem deriving implicit instances for product types.
import shapeless._
// typeclass for total number of fields (just an example)
class Width[A](val toInt: Int)
object Width {
// Get an instance
implicit def apply[A](implicit A: Width[A]) = A
scala> :pa
// Entering paste mode (ctrl-D to finish)
def subsets[A](as: List[A]): List[List[A]] = {
def sub0(accum: List[List[A]], as: List[A]): List[List[A]] =
as match {
case Nil => accum
case a :: as => sub0(accum ++ accum.map(a :: _), as)
}
sub0(List(Nil), as)