forked from scala/legacy-svn-scala
-
Notifications
You must be signed in to change notification settings - Fork 0
I18n prototype
jsalvata edited this page Nov 6, 2011
·
2 revisions
This code was developped as a proof-of-concept before development of Typed XML even began. So it doesn't really use any XML, even less the current unmarshaller API -- at that time I was thinking of using operator symbols for most of the API methods -- but it shows the idea.
It is possible that uncurrying would have given a better solution than HLists, but it would be limited in the number of parameters it can take. Or maybe we should just leave the function fully curried and let the programmer add the parenthesis.
package com.gremideprogramadors.nmlb.xml
package exploration
import collection.mutable.LinkedList
import exploration.I18nUnmarshaller.MsgTag
/**
* Heterogeneous lists idea from
* http://jnordenberg.blogspot.com/2008/08/hlist-in-scala.html
* with some changes -- so bugs are mine.
*/
sealed trait HTList
final case class HTCons[L <: HTList, T](list : L, last : T) extends HTList {
def &[T](v : T) = HTCons(this, v)
}
final class HTNil extends HTList {
def &[T](v : T) = HTCons(this, v)
}
// aliases for building HList types and for pattern matching
object HTList {
type &[L <: HTList, T] = HTCons[L, T]
val & = HTCons
val htNil = new HTNil
implicit def any2HTList[T](v: T) = htNil & v
// Q: is this dangerous? Count of bugs caused by it: 0 since 8-oct-2011
}
import HTList._
/**
* Example: slightly more advanced internationalization.
*
* Extend the previous example with placeholders (in this case, for numeric arguments).
*/
object I18nTest extends App {
println(<msg name="chance">Pay each player <currency/> and <currency/> to the bank.</msg>)
val msg= I18nUnmarshaller.msg.name("chance").++("Pay each player ").currency./.++(" and ").currency./.++(" to the bank.")./=
println(msg(2.2 & 3.3))
// Note that msg(2.2 & "hello") throws a type error when compìling
}
abstract class Msg[P <: HTList](name: Option[String], text: String) {
def apply(i: P): String
}
object I18nUnmarshaller {
def msg= new MsgTag[HTNil] {
def /= = new Msg[HTNil](_name, s.toString) {
def apply(p: HTNil) = s.toString
}
}
abstract class MsgTag[P <: HTList] {
this_tag =>
protected var _name: Option[String]= None
def name(s: String) = { _name= Some(s); this }
protected val s= new StringBuilder()
def ++(s: String) = { this.s++= s; this }
def currency = new MsgTag[P & Double] {
def / = this
def /= = new Msg[P & Double](_name, s.toString) {
def apply(p: P & Double) = p match {
case i & n => this_tag./=(i) + n.toString + "€" + s
}
}
}
def /= : Msg[P]
}
}