Skip to content

Instantly share code, notes, and snippets.

@monadplus
monadplus / safeList.scala
Created March 2, 2019 21:28
Safe List using GADT
/*
{-#LANGUAGE GADTs, EmptyDataDecls #-}
-- (the EmptyDataDecls pragma must also appear at the very top of the module,
-- in order to allow the Empty and NonEmpty datatype declarations.)
data Empty
data NonEmpty
data SafeList a b where
Nil :: SafeList a Empty
@monadplus
monadplus / existentials.scala
Created March 2, 2019 22:13
Existentially qualified types in Scala
/*
data ShowBox = forall s. Show s => SB s
heteroList :: [ShowBox]
heteroList = [SB (), SB 5, SB True]
-----
instance Show ShowBox where
show (SB s) = show s
@monadplus
monadplus / timed.scala
Created March 4, 2019 15:38
Record Execution Time with WriterT
// From https://www.softwaretalks.io/v/4720/lambda-world-2018-boring-use-cases-for-exciting-types-itamar-ravid
type Timed[A] = WriterT[Id, Map[String, FiniteDuration], A]
def timed[A](name: String, lazyA: () => A): Timed[A] =
WriterT[Id, Map[String, FiniteDuration], A] {
timed(lazyA).leftMap(duration => Map(name -> duration))
}
trait TimedOps {
def logMetric(): Unit
@monadplus
monadplus / await.scala
Last active March 13, 2019 19:15
await
import cats._
import cats.implicits._
import cats.effect._
import cats.effect.concurrent.Deferred
import cats.effect.implicits._
import scala.concurrent.duration._
object Await extends IOApp {
def await[F[_]: Concurrent, A](fa: F[A]): F[(F[Option[Either[Throwable, A]]], CancelToken[F])] =
Deferred[F, Option[Either[Throwable, A]]].flatMap { result =>
@monadplus
monadplus / overrideClass.scala
Created March 18, 2019 09:02
Class: override impure val won't prevent side-effect
class Foo {
val x = println("Foo")
}
class Bar(override val x: Unit) extends Foo
new Bar(()) // Foo is printed
// res1: Bar = ...
@monadplus
monadplus / generics.hs
Created March 19, 2019 22:51
Generics in Haskell
{-# LANGUAGE DefaultSignatures, DeriveGeneric, TypeOperators, FlexibleContexts #-}
import GHC.Generics
import Data.Bits
data Bit = O | I deriving Show
class Serialize a where
put :: a -> [Bit]
@monadplus
monadplus / compose.scala
Created March 20, 2019 07:29
Kind projector function syntax
// underlying: Ref[F, A]
// trans: F ~> G
// underlying.access: F[(A, A => F[Boolean])]
// Mapping from F[(A, A => F[Boolean])] to G[(A, A => G[Boolean])]
override def access: G[(A, A => G[Boolean])] =
trans(F.compose[(A, ?)].compose[A => ?].map(underlying.access)(trans(_)))
// Step by Step
@monadplus
monadplus / exercise_deferred.scala
Created March 20, 2019 08:41
Exercise: implement cats.Deferred from scratches
// Original code from https://github.com/typelevel/cats-effect/blob/1846813109b1e78c5bf36e6e179d7a91419e01d0/core/shared/src/main/scala/cats/effect/concurrent/Deferred.scala#L164
// Exercise: implement deferred
// Bear in mind:
// - always use compareAndSet when updating the atomic reference
// - don't break RT when dealing with ref (i.e. F.delay, F.suspend)
// - `get` should be cancelable.
// - `complete` should return a F[Unit] that does not block the current ec.
// - `register` and `unregister` methods should be tail-recursive.
@monadplus
monadplus / killing-actor.scala
Created April 1, 2019 07:00
Killing an actor is a cooperative task
// Stopping the loop actor:
// - Raw PoisonPill didn't work.
// - context.stop(loopActor) didn't work.
// - Thread.interrupted() is never triggered by PoisonPill, Kill nor stop.
class LoopActor extends Actor {
var isInterrupted = false
override def postStop(): Unit = println("Stopping...")
override def receive: Receive = {
@monadplus
monadplus / actorRef.scala
Last active April 5, 2019 10:05
ActorRef
package com.stuart.dispatcher
import akka.actor.ActorRef
import io.estatico.newtype.macros.newtype
package object model {
trait TC1[T, A] {
def apply(a: A): T
}
implicit class ActorRefSyntax(self: ActorRef) {