Reputation: 1613
Is it possible to define generic operators in Scala?
Scala lets me map arbitrary operators on functions, which is incredibly useful. It seems restrictive however, in a case where I might want the operators to change given the state of the application.
To give an example: I have a table with users and a table with their respective relationships. Each relationship has a type, such as: "friends-with", "works-with", etc.
Based on my domain model, I would like the DSL to allow for: is(john friends-with mary)
. In this case, both john
and mary
would be of Object User
, which would have a generic operator def <relationship> (a:User): Boolean = {...}
.
What I wanted to achieve was exactly what Dynamic would allow me to do (see answer). The description fits perfectly:
A marker trait that enables dynamic invocations. Instances x of this trait allow calls x.meth(args) for arbitrary method names meth and argument lists args. If a call is not natively supported by x, it is rewritten to x.applyDynamic("meth", args).
More information here: http://www.scala-lang.org/api/current/scala/Dynamic.html
Upvotes: 0
Views: 421
Reputation: 297265
Look at trait Dynamic, which will be available on Scala 2.10 (it's experimental on Scala 2.9).
For example:
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class User(name: String) extends Dynamic {
def applyDynamic(relationship: String)(to: User) =
Relation(relationship, this, to)
}
case class Relation(kind: String, from: User, to: User)
// Exiting paste mode, now interpreting.
defined class User
defined class Relation
scala> User("john") friendsWith User("mary")
res0: Relation = Relation(friendsWith,User(john),User(mary))
Upvotes: 4