Skip to content

Instantly share code, notes, and snippets.

View fommil's full-sized avatar
having a fantastic day not writing any scala

>>= fommil

having a fantastic day not writing any scala
View GitHub Profile
package shapely
import scala.annotation._
sealed trait Shape[A]
sealed trait CaseClass[A] extends Shape[A] { def value(i: Int): Any }
sealed trait SealedTrait[A] extends Shape[A] { def value: A ; def index: Int }
final case class CaseClass0[A]() extends CaseClass[A] { def tuple: Unit = () ; override def value(i: Int): Any = throw new IllegalArgumentException }
case object CaseClass0 { def untuple[A](): CaseClass0[A] = apply[A]() }
fommil /
Last active February 23, 2019 19:26
Local Capabilities with MTL

MTL is a popular approach to writing applications in Haskell. Monad constraints provide capabilities such as error handling (MonadError), writable state (MonadState), and environmental context (MonadReader). An application typically has one monad stack, implemented as a monad transformer.

However, a common problem with MTL is that the capabilities are global and the requirements of individual components may conflict. For example, an HTTP component may require a MonadError ServantError whereas a DB component may require something else. A typical workaround is to introduce a monolithic error ADT, and an unfortunate level of coupling. The problem repeats for other capabilities.

In this post, we will demonstrate a way to encode capabilities that remain local to a single component. Our example builds on the Servant Tutorial and will also show how Servant client endpoints can be mocked out for unit testing. This post is a transcript

fommil / broken
Created June 19, 2018 07:57
X logs: keyboard not working
[ 8.219]
X.Org X Server 1.20.0
X Protocol Version 11, Revision 0
[ 8.219] Build Operating System: Linux Arch Linux
[ 8.219] Current Operating System: Linux Samurai 4.17.2-1-ARCH #1 SMP PREEMPT Sat Jun 16 11:08:59 UTC 2018 x86_64
[ 8.219] Kernel command line: initrd=\intel-ucode.img initrd=\initramfs-linux.img root=PARTUUID=dad2fe1c-e20e-4ddd-b108-08db7e7a1270 rw amdgpu.dc=0
[ 8.219] Build Date: 17 June 2018 05:28:05AM
[ 8.219]
[ 8.219] Current version of pixman: 0.34.0
[ 8.219] Before reporting problems, check
package net.cakesolutions
import scala.util.Try
import scala.sys.process._
import sbt._
import sbt.Keys._
import com.typesafe.sbt.packager.Keys._
import com.typesafe.sbt.packager.docker._
import scalaz._
def foo(x: String \/ Int) = {
x match {
case -\/(s) => println("I'm a String")
case \/-(i) => println("I'm an Int")
case _ => println("I cannot be anything else 'cuz compiler guarantees it!")
// Copyright: 2017 Sam Halliday
// License:
package scalaz
import scala.Option
import Scalaz._
sealed abstract class /~\[F[_], C[_]] {
type T
package com.example
import cats._, data._, effect._
import doobie.hikari.imports._
import doobie.imports._
import fs2.interop.cats._
import fs2.util.{ Catchable, Suspendable }
import Fragments._
package net.cakesolutions
import scala.sys.process._
import scala.util.Try
import sbt._
import sbt.Keys._
import com.typesafe.sbt.packager.Keys._
import com.typesafe.sbt.packager.docker._
val `shapeless.LabelledGeneric` = {
def `shapeless.LabelledGeneric.Aux` = scala.Predef.???
implicit val `shapeless.LabelledGeneric.Aux`
: shapeless.LabelledGeneric.Aux[Bar, `shapeless.LabelledGeneric`.Repr] =
[info] java.lang.NoSuchMethodError: xmlformat.examples.Optimal$: method <init>()V not found
[info] at xmlformat.examples.Optimal$.<clinit>(examples.scala)
[info] at xmlformat.EncoderTests.$anonfun$new$16(EncoderTests.scala:113)
[info] at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
ModuleDef(Modifiers(), TermName("Optimal"), Template(List(), noSelfType, List(ValDef(Modifiers(IMPLICIT), TermName("xmlformat$u002EEncoder"), AppliedTypeTree(Select(Ident(xmlformat), TypeName("Encoder")), List(Ident(TypeName("Optimal")))), Apply(Select(TypeApply(Select(Select(Select(Ident(termNames.ROOTPKG), TermName("scala")), TermName("Predef")), TermName("implicitly")), List(AppliedTypeTree(Select(Ident(xmlformat), TypeName("Encoder")), List(Ident(TypeName("String")))))), TermName("xmap")), List(Function(List(ValDef(Modifiers(PARAM | SYNTHETIC), TermName("x"), TypeTree(), EmptyTree)), Apply(Select(New(Ident(TypeName("Optimal"))), termNames.CONSTRUCTOR), List(Ident(TermName("x"))))), Function(List(ValDef(Modifi