Skip to content

Instantly share code, notes, and snippets.

View ceedubs's full-sized avatar

Cody Allen ceedubs

  • central Indiana, USA
View GitHub Profile
@ceedubs
ceedubs / WriterExample.scala
Last active August 27, 2021 05:27
Using the Writer monad for log messages
object WriterExample extends App {
import scalaz._
// DList has constant time append, which is nice for logging
// for simplicity we will just use String for logs, but you could
// get fancier and have a model with Error, Warn, Info, Debug, etc.
type Logged[A] = Writer[DList[String], A]
def log(msg: String): Logged[Unit] = WriterT.tell(DList(msg))
@ceedubs
ceedubs / OrderingContravariantExample.scala
Created November 20, 2014 13:17
Contravariant[Ordering]
import scalaz._
import scala.math.Ordering
implicit val orderingContra: Contravariant[Ordering] = new Contravariant[Ordering] {
def contramap[A, B](r: Ordering[A])(f: B => A): Ordering[B] = r.on(f)
}
case class Doodad(description: String, priceCents: Int)
import scalaz.syntax.contravariant._
@ceedubs
ceedubs / gist:d705dc450596ae75e45c
Last active August 29, 2015 14:07
Turning List[Int => Int] into Int => List[Int] with cosequence
import scalaz.std.function._
import scalaz.syntax.functor._
import scalaz.Functor
/* https://gist.github.com/ceedubs/f8273ede78f86df7df7f shows we can do this with sequenceU.
* Stephen Compall (S11001001) pointed out that cosequence can do this without requiring a
* Traverse instance of the outer type by using the Distributive instance of the inner type.
* (It still requires a Functor instance of the outer type, but many types such as Task, Future,
* etc have Functor but not Traverse.)
*/
@ceedubs
ceedubs / gist:f8273ede78f86df7df7f
Last active August 29, 2015 14:07
Turning List[Int => Int] into Int => List[Int] with sequenceU
import scalaz.std.list._
import scalaz.std.function._
import scalaz.syntax.traverse._
val add1: Int => Int = _ + 1
val times2: Int => Int = _ * 2
val squared: Int => Int = n => n * n
// sequenceU requires that List has a Traverse instance
// and that Function1 (for Int => Int in this case) has an Applicative instance
// luckily, scalaz provides both
@ceedubs
ceedubs / gist:a96bc169eb3152cd6226
Created September 30, 2014 22:17
Scalaz's Equal type class (and associated handy === syntax) is a type-safe alternative to Scala's ==
scala> case class UserId(id: Long)
defined class UserId
scala> def isSusan(id: UserId): Boolean = id == 3L // see the bug?
isSusan: (id: UserId)Boolean
scala> isSusan(UserId(3L))
res31: Boolean = false// shouldn't this be true?
// let's show the compiler how to check whether two UserIds are equal
@ceedubs
ceedubs / gist:cd2e11ef9b786066a8ba
Created September 30, 2014 18:49
Scalaz traverse example
/* traverse takes an F[A] and an A => G[B] and returns a G[F[B]].
* In this case List[Long] and Long => Option[String] result in Option[List[String]]
*/
scala> val usernames = Map(1L -> "susie", 2L -> "bob")
usernames: scala.collection.immutable.Map[Long,String] = Map(1 -> susie, 2 -> bob)
scala> List(1L, 2L).traverse(usernames.get)
res2: Option[List[String]] = Some(List(susie, bob))
scala> List(1L, 2L, 3L).traverse(usernames.get)
@ceedubs
ceedubs / TypeLevelFizzBuzz.scala
Last active August 29, 2015 13:58
Type level FizzBuzz
package typelevelfizzbuzz
import Nat._
sealed trait Nat
object Nat {
sealed trait _0 extends Nat
sealed trait Succ[T <: Nat] extends Nat
type _1 = Succ[_0]
@ceedubs
ceedubs / gist:9345388
Created March 4, 2014 12:10
Using Scala type tags to ensure that a String is lower case. At compile time we can require a String @@ LowerCase (that is, a String that we are promising is lower case). However at runtime there is no extra boxing, so we don't have the overhead we would have if we wrapped strings in a LowerCase class.
scala> import scalaz.{ @@, Tag }
import scalaz.{$at$at, Tag}
scala> sealed trait LowerCase
defined trait LowerCase
// as an optimization you could also define a TrustMeLowerCase method that doesn't call toLowerCase if you know your input is already lower case
scala> def LowerCase(s: String): String @@ LowerCase = Tag[String, LowerCase](s.toLowerCase)
LowerCase: (s: String)scalaz.@@[String,LowerCase]
@ceedubs
ceedubs / gist:8589661
Created January 24, 2014 00:22
Defining type alias ErrorsOrT to use liftM on EitherT instances without using a type lambda
scala> import scalaz.syntax.id._ // for .right
import scalaz.syntax.id._
scala> import scalaz.EitherT
import scalaz.EitherT
scala> import scalaz.NonEmptyList
import scalaz.NonEmptyList
scala> import scala.concurrent.Future
scala> val vs = 1.success[String] :: 2.success[String] :: Nil
vs: List[scalaz.Validation[String,Int]] = List(Success(1), Success(2))
scala> vs.traverseU(_.toValidationNel)
res9: List[scalaz.Validation[scalaz.NonEmptyList[String],Int]] = List(Success(1), Success(2))