Skip to content

Instantly share code, notes, and snippets.

@nbenns
Created April 21, 2018 13:36
Show Gist options
  • Save nbenns/744d6d3bc008067523e183bfbc58c2b2 to your computer and use it in GitHub Desktop.
Save nbenns/744d6d3bc008067523e183bfbc58c2b2 to your computer and use it in GitHub Desktop.
sealed trait Json
case class JsonString(value: String) extends Json
sealed trait Yaml
case class YamlString(value: String) extends Yaml
object Symbols {
type |>[From, To] = Converter[From, To]
type <|[To, From] = Converter[From, To]
}
import Symbols._
trait Converter[From, To] {
def apply(from: From): Option[To]
}
object Converter {
def apply[From, To](from: From)(implicit converter: From |> To): Option[To] = converter(from)
def apply[FromA, FromB, ToA, ToB](f: FromA => FromB)
(implicit cfa: FromA <| ToA, cfb: FromB |> ToB): ToA => Option[ToB] =
toa => cfa(toa).map(f).flatMap(cfb.apply)
implicit def compose[From, Mid, To](implicit step1: From |> Mid, step2: Mid |> To): From |> To =
from => step1(from).flatMap(step2.apply)
}
object Main extends App {
implicit val stringToJsonString: String |> JsonString = from => Some(JsonString(from))
implicit val jsonStringToString: JsonString |> String = from => Some(from.value)
implicit val stringToYamlString: String |> YamlString = from => Some(YamlString(from))
implicit val yamlStringToString: YamlString |> String = from => Some(from.value)
val jstring = JsonString("meow")
val optYamlString = Converter[JsonString, YamlString](jstring)
val f: String => String = s => s + "meow"
val jf: JsonString => Option[JsonString] = Converter[String, String, JsonString, JsonString](f)
println(optYamlString)
println(jf(JsonString("blah")))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment