Skip to content

Instantly share code, notes, and snippets.

@jprudent
Created February 10, 2023 08:55
Show Gist options
  • Save jprudent/aee4f4d0f9eba64110565bed6c73cfb5 to your computer and use it in GitHub Desktop.
Save jprudent/aee4f4d0f9eba64110565bed6c73cfb5 to your computer and use it in GitHub Desktop.
extension-problem-functional-way.sc
import VendorLib.JsonString
// rules :
// 1) You can't change VendorLib
// 2) You can't change UserCode
// 3) Type safety
object VendorLib {
sealed trait Json
case class JsonString(s: String) extends Json
case class JsonArray(a: Seq[Json]) extends Json
case class JsonObject(m: Map[String, Json]) extends Json
}
object UserLib {
trait Alive
case class Human(name: String, like: Seq[Alive]) extends Alive
case class Dog(companion: Human) extends Alive
import VendorLib.*
def toJson(x: Alive): Json = x match
case Human(name, like) => JsonObject(Map("name" -> JsonString(name), "like" -> JsonArray(like.map(l => toJson(l)))))
case Dog(companion) => JsonObject(Map("companion" -> toJson(companion)))
}
val louis = UserLib.Human("louis", List.empty)
val satan = UserLib.Dog(louis)
val jerome = UserLib.Human("jerome", List(satan))
println(UserLib.toJson(jerome))
object UserLib2 {
case class Plant() extends UserLib.Alive
import UserLib.*
import VendorLib.*
def toUppercaseJson(x: UserLib.Alive): VendorLib.Json = x match
case Human(name, like) =>
JsonObject(Map("NAME" -> JsonString(name), "LIKE" -> JsonArray(like.map(l => toUppercaseJson(l)))))
case Dog(companion) => JsonObject(Map("COMPANION" -> toUppercaseJson(companion)))
case Plant() => JsonString("i am a plant".toUpperCase)
}
val arbre = UserLib2.Plant()
val roger = UserLib.Human("roguer", List(arbre))
println(UserLib2.toUppercaseJson(roger))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment