Last active
April 5, 2021 08:43
-
-
Save markus1189/b356afed7b16e46a5ecfb1a3060d3296 to your computer and use it in GitHub Desktop.
Using given for a function argument in Scala 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example from https://www.scala-lang.org/blog/2016/12/07/implicit-function-types.html | |
import scala.collection.mutable.ListBuffer | |
import scala.util.chaining.* | |
class Transaction: | |
private val log = ListBuffer[String]() | |
private var aborted = false | |
private var committed = false | |
def println(s: String): Unit = | |
log += s | |
def abort(): Unit = | |
aborted = true | |
def isAborted = | |
aborted | |
def commit(): Unit = | |
if !aborted && !committed then | |
Console.println("******* log ********") | |
log.foreach(Console.println) | |
committed = true | |
object Transaction: | |
type Transactional[T] = Transaction ?=> T | |
def thisTransaction: Transactional[Transaction] = | |
summon[Transaction] | |
// literal translation from blog post | |
def transaction1[T](op: Transactional[T]) = | |
given trans: Transaction = Transaction() | |
op | |
trans.commit() | |
// using Scala 2's implicit | |
def transaction2[T](op: Transactional[T]) = | |
Transaction().tap(implicit _ => op).commit() | |
// using pattern match in Scala 3 | |
def transaction3[T](op: Transactional[T]) = | |
Transaction().tap { case _ @ given Transaction => op }.commit() | |
// using ?=> | |
def transaction4[T](op: Transactional[T]) = | |
Transaction().tap(x => op(using x)).commit() | |
// using explicit application, would like to avoid | |
def transaction5[T](op: Transactional[T]) = | |
Transaction().tap(x => op(using x)).commit() | |
Transaction().tap(op(using _)).commit() // would also work with underscore | |
extension [A](self: A) | |
def contextTap[U](f: A ?=> U): A = | |
f(using self) | |
self | |
// using custom tap extension | |
def transaction6[T](op: Transactional[T]) = | |
Transaction().contextTap(op).commit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment