I know that scala allows overloading for it's default operators (+, - ! etc.) . Is it possible to define custom operators and make something like the |.| operator so that | -3| that evaluates to 3. Or defining an operator like ++++ so that a ++++ b equals a+3*b?
2 Answers
You should look at scala operators documentation.
You can easily make the ++++ operator but not the |.| operator.
Operators in scala are just functions with non alphanumeric name. Since scala also support call a.f(b) as a f b then you can achieve the first behavior. For example:
case class A(v: Int) {
def ++++(b: A): A = A(v + 3 * b.v)
}
val a = A(1)
val b = A(2)
a ++++ b
>> A(7)
a.++++(b) // just another way of doing the exact same call
If you want to add this to integer you would simply create an implicit class to add it.
Another option is to prefix the operator for example consider doing -a to get the negative. There is no "first element" to apply the - to, instead - is applied to a (see this answer).
For example:
case class A(v: Int) {
def unary_!(): Int = -v
}
val a = A(3)
!a
>> -3
Doing |.| has two issues: First there are two parts to the operator, i.e. it is split. The second is the use of |
In order to do a two part operator (say !.!) you would probably want to generate some private type and return it from one ! and then use it as the input for the other to return the output type.
The second issue is the use of | which is an illegal character. Look at this answer for a list of legal characters

- 12,701
- 5
- 47
- 56
-
`|` is legal though and it's listed as legal in the answer you've linked. – Kolmar Jun 27 '17 at 14:30
-
You are correct, it appears as legal from the answer, however, that specific character doesn't seem to work (at least in the REPL) There must be another limitation I missed. – Assaf Mendelson Jun 27 '17 at 14:47
-
Hm, for me it works normally as a method: `class A { def |(int: Int) = int * 2; def ||(int: Int) = int * 3; def |||(int: Int) = int * 4 }; new A || 2 // returns 6`. It doesn't work as `unary_|` and I believe only `unary_-` and `unary_!` are supported as prefix operators. – Kolmar Jun 27 '17 at 15:01
-
The thing is that the OP asked for `|x|` having `|` as delimiter. It still can be done but doesn't will be clumsy. – pedrofurla Jun 27 '17 at 21:45
An example to extend @assaf-mendelson answer
case class Abs(a: Int) {
def !(): Int = a.abs
}
implicit def toAbs(a: Int) = new {
def unary_! : Abs = Abs(a)
}
then
> val a = -3
a: Int = -3
> !a
res0: Abs = Abs(-3)
> !a!
res1: Int = 3
> val b = 12
b: Int = 12
> !b!
res2: Int = 12
> (!a!) + (!b!)
res3: Int = 15
We cannot implement abs as |a|
because unary_
works only with !
, ~
, +
and -

- 4,272
- 1
- 19
- 22
-
The code does not work, neither with Scala 3 nor with Scala 2 (3.1.3 and 2.11.12) – 18446744073709551615 Sep 04 '22 at 20:54