Skip to content

Instantly share code, notes, and snippets.

@halcat0x15a
Created July 6, 2011 11:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halcat0x15a/1067037 to your computer and use it in GitHub Desktop.
Save halcat0x15a/1067037 to your computer and use it in GitHub Desktop.
Real World Haskellを参考にJSONを表現してみた。
package json
sealed abstract class JValue[+A](value: A)
case class JString(value: String) extends JValue(value) {
override def toString = "\"" + value + "\""
}
case class JNumber(value: Double) extends JValue(value) {
override def toString = value.toString
}
case class JBoolean(value: Boolean) extends JValue(value) {
override def toString = value.toString
}
object JNull extends JValue(null) {
override def toString = "null"
}
case class JObject(value: (JString, JValue[_])*) extends JValue(value) {
override def toString = (value.map {
case (s, v) => s.toString + ":" + v.toString
}).mkString("{", ",", "}")
}
case class JArray(value: JValue[_]*) extends JValue(value) {
override def toString = value.map(_.toString).mkString("[", ",", "]")
}
package object json {
implicit def stringToJString(s: String) = JString(s)
implicit def doubleToJNumber(n: Double) = JNumber(n)
implicit def booleanToJBoolean(b: Boolean) = JBoolean(b)
implicit def stringJValueAToJStringJValueA[A](t: (String, JValue[A])) = t match {
case (s, v) => JString(s) -> v
}
implicit def stringAToJStringJValueA[A](t: (String, A))(implicit f: A => JValue[A]) = t match {
case (s, v) => JString(s) -> f(v)
}
lazy val anyToJValue: PartialFunction[Any, JValue[_]] = {
case m: Map[_, _] => mapToJObject(m)
case l: List[_] => listToJArray(l)
case d: Double => JNumber(d)
case b: Boolean => JBoolean(b)
case s: String => JString(s)
case _ @ a => if (a == null) JNull else throw new MatchError
}
implicit def listToJArray(l: List[_]) = JArray(l.map(anyToJValue): _*)
implicit def mapToJObject(m: Map[_, _]) = JObject(m.toSeq.map {
case (s: String, a) => JString(s) -> anyToJValue(a)
}: _*)
def parse(input: String) = JSON.parseFull(input).map {
case m: Map[_, _] => mapToJObject(m)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment