Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h2>The alternative approach</h2> <p><em>In addition to the direct solution of</em> pattern matching <em>in your method, I'll try to show a somewhat more convoluted, general and functional approach to this kind of situations. Still pattern matching is the most</em> direct and simple <em>answer!</em></p> <hr> <p>If you can explicitly "certify" in your interface the <code>input</code> accessor, you can generalize how you work with the <code>Something</code> class.</p> <p>In code this translates to</p> <pre><code>trait Something[T] { def input: T } case class Foo(input: Int) extends Something[Int] case class Bar(input: Double) extends Something[Double] </code></pre> <hr> <p>from here you can define how to "lift" any function you like to one that works over <code>Something</code>s</p> <p>Let's say you have methods that takes two inputs (e.g. <code>Ints</code> or <code>Doubles</code>) and you want to operate on such inputs within one of your case classes (i.e. <code>Foo</code>, <code>Bar</code>)</p> <pre><code>//this function lift your specific input method to one that takes Somethings def liftSomething2[T, R](f: (T, T) =&gt; R): (Something[T], Something[T]) =&gt; R = (a, b) =&gt; f(a.input, b.input) </code></pre> <p>Let's examine this a bit: it takes a function<br> <code>(T, T) =&gt; R</code> of 2 arguments of type <code>T</code> and a result <code>R</code></p> <p>and transforms it in a<br> <code>(Something[T], Something[T]) =&gt; R</code> which takes <code>Something</code>s as arguments.</p> <p><strong>Examples</strong></p> <pre><code>//lifts a function that sums ints scala&gt; val sumInts = liftSomething2[Int, Int](_ + _) sumInts: (Something[Int], Something[Int]) =&gt; Int = &lt;function2&gt; //lifts a function that multiplies ints scala&gt; val multInts = liftSomething2[Int, Int](_ * _) multInts: (Something[Int], Something[Int]) =&gt; Int = &lt;function2&gt; //lifts a function that divides doubles scala&gt; val divDbl = liftSomething2[Double, Double](_ / _) divDbl: (Something[Double], Something[Double]) =&gt; Double = &lt;function2&gt; //Now some test scala&gt; sumInts(Foo(1), Foo(2)) res2: Int = 3 scala&gt; multInts(Foo(4), Foo(-3)) res3: Int = -12 scala&gt; divDbl(Bar(20.0), Bar(3.0)) res4: Double = 6.666666666666667 //You can even complicate things a bit scala&gt; val stringApp = liftSomething2[Int, String](_.toString + _) stringApp: (Something[Int], Something[Int]) =&gt; String = &lt;function2&gt; scala&gt; stringApp(Foo(1), Foo(2)) res5: String = 12 </code></pre> <hr> <p>All the above examples lift functions of type <code>(T,T) =&gt; R</code> but the "lifting" can be made for all and any argument you need</p> <pre><code>//This takes three args of different types and returns another type // the logic doesn't change def liftSomething3[A,B,C,R](f: (A,B,C) =&gt; R): (Something[A], Something[B], Something[C]) =&gt; R = (a,b,c) =&gt; f(a.input, b.input, c.input) //sums to ints and divides by a double scala&gt; val sumDiv = liftSomething3[Int,Int,Double,Double]((i,j,d) =&gt; (i + j) / d) sumDiv: (Something[Int], Something[Int], Something[Double]) =&gt; Double = &lt;function3&gt; scala&gt; sumDiv(Foo(5), Foo(30), Bar(4.2)) res7: Double = 8.333333333333332 </code></pre> <h2>more...</h2> <p>All we've seen so far should be somewhat related to <em>category theory</em> concepts like <em>Applicative Functors</em> and <em>Comonads</em>, but I'm no expert so I encourage you to search for yourself if you feel this sort of abstractions are useful and interesting.</p>
 

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