Skip to content

Instantly share code, notes, and snippets.

@dwijnand
Last active March 7, 2019 22:34
Show Gist options
  • Save dwijnand/7dacd40dbbe1aa467b12eaf7fa985cb5 to your computer and use it in GitHub Desktop.
Save dwijnand/7dacd40dbbe1aa467b12eaf7fa985cb5 to your computer and use it in GitHub Desktop.
Rust's From/Into ported to Conversion.scala
-sbt-version
1.2.7
//sbt.version=1.2.7
val frominto = project in file(".")
scalaVersion := "2.12.8"
addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.6")
package frominto
// Rust's From and Into in Scala
/** Simple, safe and pure conversion from `A` into `B`. */
trait Conversion[-A, +B] {
def convert(value: A): B
}
object Conversion {
implicit def refl[A]: Conversion[A, A] = x => x
implicit def optionConvert[A]: Conversion[A, Option[A]] = x => Option(x)
implicit class Syntax[A](private val value: A) extends AnyVal {
def convert[B](implicit c: Conversion[A, B]): B = c.convert(value)
}
}
object Main {
import Conversion.Syntax
def foo2[I, D, S](lorem: String, ipsum: I, dolor: D, sit: S)(implicit
I: Conversion[I, Option[Int]],
D: Conversion[D, Option[Int]],
S: Conversion[S, Option[Int]],
) = {
val ipsum2 = ipsum.convert getOrElse 0
val dolor2 = dolor.convert getOrElse 0
val sit2 = sit.convert getOrElse 0
println(s"$ipsum2 $lorem $dolor2 $sit2")
}
def setReadTimeout3[A: Conversion[?, Option[Int]]](timeout: A) = {
timeout.convert match {
case Some(x) => println(s"set timeout to $x")
case None => println(s"unset timeout")
}
}
def main(args: Array[String]): Unit = {
foo2("bar", None, None, None)
foo2("bar", 42, None, None)
foo2("bar", 42, 1337, None)
foo2("bar", 42, 1337, -1)
setReadTimeout3(10)
setReadTimeout3(None)
}
type Marshaller[A]
type StatusCode
type HttpResponse
import scala.concurrent.Future
/** WARNING, side effecting, changes the world */
sealed trait CompletionMagnet {
type Result
def finish(): Result
}
object CompletionMagnet {
implicit def fromStatusObject[T: Marshaller](tuple: (StatusCode, T)) =
new CompletionMagnet {
type Result = Unit
def finish(): Result = ??? // implementation using (StatusCode, T) tuple
}
implicit def fromHttpResponseFuture(future: Future[HttpResponse]) =
new CompletionMagnet {
type Result = Int
def finish(): Result = ??? // implementation using future
}
implicit def fromStatusCodeFuture(future: Future[StatusCode]) =
new CompletionMagnet {
type Result = Int
def finish(): Result = ??? // implementation using future
}
}
def complete[M, N <: CompletionMagnet](magnet: M)(implicit M: Conversion[M, N]): N#Result =
magnet.convert.finish()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment