Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to create a custom operator simulating dot (without parentheses)?
    primarykey
    data
    text
    <p>Let's have this code:</p> <pre class="lang-scala prettyprint-override"><code>scala&gt; case class Num(n:Int){def inc = Num(n+1)} defined class Num scala&gt; implicit class Pipe(n:Num){ def | = n } defined class Pipe </code></pre> <p>This works:</p> <pre class="lang-scala prettyprint-override"><code>scala&gt; (Num(0) |) inc res7: Num = Num(1) </code></pre> <p>But is it possible to somehow (maybe implicits or macros?) make Scala to run sample bellow in a same way as the code with parentheses without modifying <code>Num</code> class?</p> <pre class="lang-scala prettyprint-override"><code>scala&gt; Num(0) | inc &lt;console&gt;:11: error: Num does not take parameters Num(0) | inc ^ </code></pre> <p>Wanted result is:</p> <pre class="lang-scala prettyprint-override"><code>scala&gt; Num(0) | inc | inc res8: Num = Num(2) </code></pre> <hr> <p>EDIT:<br> Here's code that's much closer to the real thing. I hope this is more understandable.</p> <pre><code>object ApplyTroubles2 extends App { import GrepOption.GrepOption abstract class Builder { var parent: Builder = null def getOutput: String def append(ch: Builder) = { ch.parent = this; ch } def echo(s: String) = append(new Echo(s)) def wc() = append(new Wc()) def grep(s: String, opts: Set[GrepOption]) = append(new Grep(s, opts)) def grep(s: String) = append(new Grep(s)) } object MainBuilder extends Builder { def getOutput: String = "" override def append(ch: Builder): Builder = ch } class Echo(data: String) extends Builder { def getOutput = data } class Wc() extends Builder { def getOutput = parent.getOutput.size.toString } class Grep(var pattern: String, options: Set[GrepOption]) extends Builder { def this(pattern: String) = this(pattern, Set.empty) val isCaseInsensitive = options.contains(GrepOption.CASE_INSENSITIVE) if (isCaseInsensitive) pattern = pattern.toLowerCase def getOutput = { val input = if (isCaseInsensitive) parent.getOutput.toLowerCase else parent.getOutput if (input.contains(pattern)) input else "" } } object GrepOption extends Enumeration { type GrepOption = Value val CASE_INSENSITIVE = Value } object BuilderPimps { // val wc: Builder =&gt; Builder = x =&gt; x.wc() // def echo(msg: String): Builder =&gt; Builder = x =&gt; x.echo(msg) } implicit class BuilderPimps(b: Builder) { // as suggested in one answer, should solve calling an apply method // def |(fn: Builder =&gt; Builder): Builder = fn(b) def | : Builder = b def getStringOutput: String = b.getOutput def &gt;&gt; : String = getStringOutput } import MainBuilder._ // working println(echo("xxx").wc().getOutput) println(echo("str") getStringOutput) println((echo("y") |) wc() getStringOutput) println(((((echo("y") |) echo ("zz")) |) wc()) &gt;&gt;) println(((echo("abc") |) grep ("b")) &gt;&gt;) println((echo("aBc") |) grep("AbC", Set(GrepOption.CASE_INSENSITIVE)) getStringOutput) // not working println((echo("yyyy") | wc()) getStringOutput) println(echo("yyyy") | wc() getStringOutput) println((echo("y")|) grep("y") &gt;&gt;) println(echo("x") | grep("x") | wc() &gt;&gt;) } </code></pre> <p>I realize that wanted operator adds no extra value in terms of functionality, it's supposed to be just a syntactic sugar to make things look nicer (in this case I'm trying to mimic the shell piping).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload