Reputation: 335
I try to build a simple implicit class on Int
to add a function for Ints:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
}
}
To be more natural to write, I would like the DSL to allow this (with import Helper._
):
2 add "3" and add "4"
but I cannot figure out how to do the and
function. I thought this one would work:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
def and: Int = i
}
}
but it does not work without the parentheses (indeed, "2.add("3").and.add("4")
works but imo there are too many full-stops and parentheses for a DSL).
Thanks
Upvotes: 4
Views: 124
Reputation: 13618
The problem is exactly as 0__ has described. I haven't seen a way how to achieve this entirely without parenthesis other than 0__'s solution.
As an alternative, here is a version that requires parenthesis only around chained add
calls, which is less than the original solution, and doesn't need an extra keyword:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
def and(add: AddWord): Int = i + add.str.toInt
}
val add = AddWord
case class AddWord(private[Helper] val str: String)
}
Which can be used as:
import Helper._
1 add "3" and add("4") and add("5")
Upvotes: 1
Reputation: 67290
The problem with this is that and
is now used as in postfix notation, something that is generally advised against because it creates exactly the problem with delimiting the expression. So you may write
(2 add "3" and) add "4"
But
2 add "3" and add "4"
is approximately parsed as
2.add("3").and(add)."4"
I would recommend against such DSL. Especially when coming new to Scala, people are intrigued by the expressiveness of Scala that allows these kind of DSLs, but you have to question hard what value lies in them.
If you really want to pursue this path, you can make things "symmetric" again by turning the dummy and
method from postfix to infix, adding another dummy argument, e.g. then
:
object Helper {
implicit class IntHelper(i: Int) {
def add(str: String): Int = i + str.toInt
}
implicit class AndThen[A](in: A) {
def and(t: then.type): A = in
}
object then
}
import Helper._
2 add "3" and then add "4"
Upvotes: 5