Skip to content

Instantly share code, notes, and snippets.

@wedens
Last active August 31, 2019 21:26
Show Gist options
  • Save wedens/a72c02e93ba6c8a490292780ad2270e6 to your computer and use it in GitHub Desktop.
Save wedens/a72c02e93ba6c8a490292780ad2270e6 to your computer and use it in GitHub Desktop.
Codensity and ContT resource management
object test {
val x = for {
_ <- new Codensity[IO, Unit] {
def apply[B](f: Unit => IO[B]): IO[B] =
f(()).ensuring(IO.putStrLn("finally"))
}
a <- new Codensity[IO, Int] {
def apply[B](f: Int => IO[B]): IO[B] =
(IO.putStrLn("acquire: 1") >| 1)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
v <- Codensity.rep(IO.putStrLn((a + 1).shows) >| a + 1)
_ <- new Codensity[IO, Int] {
def apply[B](f: Int => IO[B]): IO[B] =
(IO.putStrLn(s"acquire: $v") >| v)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
xs <- List(12, 22, 33).traverseU { v =>
new Codensity[IO, Int] {
def apply[B](f: Int => IO[B]): IO[B] =
(IO.putStrLn(s"acquire: $v") >| v)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
}
_ <- Codensity.rep(IO.putStrLn(s"SUM: ${xs.sum.shows}"))
} yield ()
x.improve.unsafePerformIO
val y = for {
_ <- ContT.apply[IO, Int, Unit] { f =>
f(()).ensuring(IO.putStrLn("finally"))
}
a <- ContT.apply[IO, Int, Int] { f =>
(IO.putStrLn("acquire: 1") >| 1)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
v <- ContT.liftM[Id, IO, Int, Int](IO.putStrLn((a + 1).shows) >| a + 1)
_ <- ContT.apply[IO, Int, Int] { f =>
(IO.putStrLn(s"acquire: $v") >| v)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
xs <- List(12, 22, 33).traverseU { v =>
ContT.apply[IO, Int, Int] { f =>
(IO.putStrLn(s"acquire: $v") >| v)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
}
_ <- ContT.liftM[Id, IO, Int, Unit](IO.putStrLn(s"SUM: ${xs.sum.shows}"))
} yield a
y.run_.unsafePerformIO
// http://scastie.org/21122
case class Hack private[Hack] (private[Hack] val run: Any)
object Hack {
def codensity[F[_]: Functor, A](f: (A => F[Hack]) => F[Hack]): Codensity[F, A] =
new Codensity[F, A] {
def apply[B](g: A => F[B]): F[B] =
f(a => g(a).map(Hack(_))).map(_.run.asInstanceOf[B])
}
}
val x2 = for {
_ <- Hack.codensity[IO, Unit](f => f(()).ensuring(IO.putStrLn("finally")))
a <- Hack.codensity[IO, Int] { f =>
(IO.putStrLn("acquire: 1") >| 1)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
v <- Codensity.rep(IO.putStrLn((a + 1).shows) >| a + 1)
_ <- Hack.codensity[IO, Int] { f =>
(IO.putStrLn(s"acquire: $v") >| v)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
xs <- List(12, 22, 33).traverseU { v =>
Hack.codensity[IO, Int] { f =>
(IO.putStrLn(s"acquire: $v") >| v)
.bracket(x => IO.putStrLn(s"release: $x"))(f)
}
}
_ <- Codensity.rep(IO.putStrLn(s"SUM: ${xs.sum.shows}"))
} yield ()
x2.improve.unsafePerformIO
}
module Main where
import Control.Monad.Codensity
import Control.Exception
import Control.Monad.Trans.Class
import Data.Traversable
main :: IO ()
main = lowerCodensity $ do
Codensity (\k -> k () `finally` putStrLn "finally")
a <- Codensity (bracket (putStrLn "acquire: 1" *> pure 1)
(\x -> putStrLn ("release: " ++ show x)))
v <- lift $ print (a + 1) *> pure (a + 1)
Codensity (bracket (putStrLn ("acquire: " ++ show v) *> pure v)
(\x -> putStrLn ("release: " ++ show x)))
xs <- for [12, 22, 33] $ \v' ->
Codensity (bracket (putStrLn ("acquire: " ++ show v') *> pure v')
(\x -> putStrLn ("release: " ++ show x)))
lift $ putStrLn ("SUM: " ++ show (sum xs))
/***
scalaVersion := "2.11.8"
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.2.4"
libraryDependencies += "org.scalaz" %% "scalaz-effect" % "7.2.4"
*/
object Main extends App {
import scalaz._
import Scalaz._
import scalaz.effect._
def bracketCodensity[M[_]: MonadCatchIO, A, B](before: M[A])(after: A => M[B]): Codensity[M, A] =
new Codensity[M, A] {
def apply[C](f: A => M[C]): M[C] =
MonadCatchIO.bracket(before)(after)(f)
}
(for {
_ <- new Codensity[IO, Unit] {
def apply[B](f: Unit => IO[B]): IO[B] =
f(()).ensuring(IO.putStrLn("finally"))
}
a <- bracketCodensity(IO.putStrLn("acquire: 1") >| 1)(x => IO.putStrLn(s"release: $x"))
v <- (IO.putStrLn((a + 1).shows) >| a + 1).liftM[Codensity]
_ <- bracketCodensity(IO.putStrLn(s"acquire: $v") >| v)(x => IO.putStrLn(s"release: $x"))
xs <- List(12, 22, 33).traverseU { v =>
bracketCodensity(IO.putStrLn(s"acquire: $v") >| v)(x => IO.putStrLn(s"release: $x"))
}
_ <- IO.putStrLn(s"SUM: ${xs.sum.shows}").liftM[Codensity]
} yield ()).improve.unsafePerformIO
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment