Skip to content

Instantly share code, notes, and snippets.

@milessabin
milessabin / gist:a212d946aef33811fee1
Last active August 29, 2015 14:20
Functional update of common fields of a sealed family of case classes via a case-class-like copy through the common super type ...
import shapeless._
/**
* Functional update of common fields of a sealed family of case classes
* via a case-class-like copy through the common super type ...
*/
object BaseCopyDemo extends App {
import copySyntax._
// Sealed family of case classes ...
def multicast[A](p1: Process[Task, A], bound: Int = 10): Process[Task, Process[Task, A]] = Process suspend {
val queues = async signalOf Set[async.mutable.Queue[A]]()
def publish(a: A): Task[Unit] = for {
qsList <- queues.discrete filter { s => !s.isEmpty } take 1 runLog
qs = qsList flatMap { _.toList }
_ <- Task gatherUnordered (qs.toList map { _ enqueueOne a })
} yield ()
@raichoo
raichoo / gist:4d88028301b452818267
Last active August 29, 2015 14:22
Polynomial functors, initial algebras and catamorphisms
{-# LANGUAGE PatternSynonyms #-}
module Polynomial where
import Prelude hiding (Maybe(..))
class Bifunctor f where
bimap :: (a -> b) -> (c -> d) -> f a c -> f b d
instance Bifunctor (,) where
bimap f g (x, y) = (f x, g y)
/**
* Free applicative functors
*/
sealed trait FreeA[F[_],A] {
/**
* The canonical monoidal natural transformation that interprets
* this free program by giving it the semantics of the applicative functor `G`.
*/
def foldMap[G[_]:Applicative](f: F ~> G): G[A] = this match {
case Pure(x) => Applicative[G].pure(x)
scala> val it = Traversable(1); it foreach (i => println(s"$i and ${it.isEmpty}"))
1 and false
scala> val it = Iterator(1); it foreach (i => println(s"$i and ${it.isEmpty}"))
1 and true
// let's imagine you have an algebra that has a constructor like the following
sealed trait Algebra[A]
case class Ext[E, A](e: E, f: E => A) extends Algebra[A]
/*
* Not at all an uncommon pattern! Basically, this is going to show up any time you're
* doing GADTs or GADT-like things, or any sort of type-aligned sequence (in any form).
* The problem is that the pattern matcher affixes types in a linear fashion, and thus
* will not unify the solution to E between the two parameters. For example:
*/
@travisbrown
travisbrown / Bar.java
Created February 2, 2016 18:48
Package private types in your public API
// src/main/java/j/bar/Bar.java
package j.bar;
abstract class Foo {
public abstract String value();
}
public class Bar {
public static Foo makeFoo() {
return new Foo() {
sealed trait Caster[A, B]
case object CastTo extends Caster[Unit, Unit]
case class Ignored[A, B]() extends Caster[A, B]
def cast[A, B]: A =:= B =
(Ignored(): Caster[A, B]) match {
case CastTo | _ => implicitly[B =:= Unit]
}
cast[String, Int]: String =:= Int
import shims.{Permute2, Permute3}
import scalaz._
object Scratch {
trait Functor[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object Functor {
anonymous
anonymous / we-are-the-cure.md
Created April 15, 2016 20:49

Explaining Miles's Magic

Miles Sabin recently opened a pull request fixing the infamous SI-2712. First off, this is remarkable and, if merged, will make everyone's life enormously easier. This is a bug that a lot of people hit often without even realizing it, and they just assume that either they did something wrong or the compiler is broken in some weird way. It is especially common for users of scalaz or cats.

But that's not what I wanted to write about. What I want to write about is the exact semantics of Miles's fix, because it does impose some very specific assumptions about the way that type constructors work, and understanding those assumptions is the key to getting the most of it his fix.

For starters, here is the sort of thing that SI-2712 affects:

def foo[F[_], A](fa: F[A]): String = fa.toString