Swappable Trait in Scala - scala

I want to define a Swappable trait with two values x,y and a swap method such that calling swap on an object inheriting from Swappable returns another object of the same type with x,y switched. My best so far is:
trait Swappable[T] {
val x: T
val y: T
def swap: Swappable[T] = {
val (a,b) = (x,y)
new Swappable[T] { val x=b; val y=a }
}
}
But this isn't what I want because the return type of swap is some anonymous class, instead of the original class I started with, so I get errors like:
def direct[S<:Swappable[Int]](s: S): S = if (s.x > s.y) s else s.swap
<console>:32: error: type mismatch;
found : Swappable[Int]
required: S
def direct[S<:Swappable[Int]](s: S): S = if (s.x > s.y) s else s.swap
^
Is it possible to do what I'm trying to do? What is the correct type signature for swap?

I don't know how to do it, but I think maybe it would help to get a better idea of what exactly you want to happen. Consider a class like
case class Foo(x: Int, y: Int) extends Swappable[Int] {
val z = x
}
Now, if you have f = Foo(1, 2), should f.swap give you a Foo where x != z? If so, there's no way within Scala to create a Foo like that. If not, what does it really mean to "swap x and y"?
Perhaps what you're really looking for is something like this:
trait Swappable[A,T] {
this: A =>
val x: T
val y: T
def cons(x: T, y: T): A
def swap = cons(y, x)
}
case class Foo(x: Int, y: Int) extends Swappable[Foo,Int] {
val z = x
def cons(x: Int, y: Int) = copy(x=x, y=y)
}
But I'm not sure.

What about something like that:
trait Swappable[T] {
type A
val x: T
val y: T
def create(a: T, b: T): A
def swap = create(y, x)
}
case MySwappable[T](x: T, y: T) extends Swappable[T] {
type A = MySwappable
def create(a: T, b: T) = MySwappable(a, b)
}

Related

why scala compiler says type arguments does not conform to bounds?

I created Combiner trait with subclasses Complex and IntCombiner and my objective is to make Matrix work with both Complex and Int. But some reason it dosen't compile saying that
[com.implicits.TestImplicits1.IntCombiner] do not conform to class Matrix's type parameter bounds [T <: com.implicits.TestImplicits1.Combiner[T]]
val m1 = new Matrix[IntCombiner](3, 3)((1 to 9).sliding(3).map {
But as my understanding goes as IntContainer is the subclass of Combiner it should work. Why such an error please explain ?
object TestImplicits1 {
trait Combiner[T] {
def +(b: T): T
def *(b: T): T
}
class Complex(r: Double, i: Double) extends Combiner[Complex] {
val real = r
val im = i
override def +(b: Complex): Complex = {
new Complex(real + b.real, im + b.im)
}
override def *(b: Complex): Complex = {
new Complex((real * b.real) - (im * b.im), real * b.im + b.real * im)
}
}
class IntCombiner(a: Int) extends Combiner[Int] {
val v = a
override def *(b: Int): Int = v * b
override def +(b: Int): Int = v + b
}
class Matrix[T <: Combiner[T]](x1: Int, y1: Int)(ma: Seq[Seq[T]]) {
self =>
val x: Int = x1
val y: Int = y1
def dot(v1: Seq[T], v2: Seq[T]): T = {
v1.zip(v2).map { t: (T, T) => {
t._1 * t._2
}
}.reduce(_ + _)
}
}
object MatrixInt extends App {
def apply[T <: Combiner[T]](x1: Int, y1: Int)(s: Seq[Seq[T]]) = {
new Matrix[T](x1, y1)(s)
}
val m1 = new Matrix[IntCombiner](3, 3)((1 to 9).sliding(3).map {
x => x map { y => new IntCombiner(y) }
}.toSeq)
}
}
F-bounded polymorphism cannot be added to an existing Int class, because Int is just what it is, it does not know anything about your Combiner traits, so it cannot extend Combiner[Int]. You could wrap every Int into something like an IntWrapper <: Combiner[IntWrapper], but this would waste quite a bit of memory, and library design around F-bounded polymorphism tends to be tricky.
Here is a proposal based on ad-hoc polymorphism and typeclasses instead:
object TestImplicits1 {
trait Combiner[T] {
def +(a: T, b: T): T
def *(a: T, b: T): T
}
object syntax {
object combiner {
implicit class CombinerOps[A](a: A) {
def +(b: A)(implicit comb: Combiner[A]) = comb.+(a, b)
def *(b: A)(implicit comb: Combiner[A]) = comb.*(a, b)
}
}
}
case class Complex(re: Double, im: Double)
implicit val complexCombiner: Combiner[Complex] = new Combiner[Complex] {
override def +(a: Complex, b: Complex): Complex = {
Complex(a.re + b.re, a.im + b.im)
}
override def *(a: Complex, b: Complex): Complex = {
Complex((a.re * b.re) - (a.im * b.im), a.re * b.im + b.re * a.im)
}
}
implicit val intCombiner: Combiner[Int] = new Combiner[Int] {
override def *(a: Int, b: Int): Int = a * b
override def +(a: Int, b: Int): Int = a + b
}
class Matrix[T: Combiner](entries: Vector[Vector[T]]) {
def frobeniusNormSq: T = {
import syntax.combiner._
entries.map(_.map(x => x * x).reduce(_ + _)).reduce(_ + _)
}
}
}
I don't know what you attempted with dot there, your x1, x2 and ma seemed to be completely unused, so I added a simple square-of-Frobenius-norm example instead, just to show how the typeclasses and the syntactic sugar for operators work together. Please don't expect anything remotely resembling "high performance" from it - JVM traditionally never cared about rectangular arrays and number crunching (at least not on a single compute node; Spark & Co is a different story). At least your code won't be automatically transpiled to optimized CUDA code, that's for sure.

ScalaMock Stubbing with default parameters

I'm trying to mock a function like
def foo(x: A, y: B, z: C = blah)
where blah is a java connection object that I don't want to create on the spot
However when I try to stub it like
(object.foo _)
.stubs(a, b)
It errors out and says overloaded method value stubs with alternatives...
because it's looking for the third parameter. Is there anyway to get around this.
I agree with Matt, but want to point out there is a wildcard syntax in ScalaMock (*) - http://scalamock.org/user-guide/matching/
trait Foo {
def foo(x: Int, y: Int, z: Int = 0): Int
}
val a: Int = ???
val b: Int = ???
val m = mock[Foo]
m.foo _ stubs(a, b, *)
You can use a wildcard when you're stubbing out your method.
The following test passes and I think is what you're looking for:
class DefaultParameterTest extends FlatSpec with Matchers with MockFactory {
class A {
def foo(x: Int, y: Int, z: Int = 0): Int = 0
}
it should "work with a default parameter" in {
val bar = mock[A]
(bar.foo _).stubs(1, 2, _: Int).returning(5)
bar.foo _ expects(1, 2, 0) returning 5 once()
bar.foo(1, 2)
}
}

generic type-based function to sum numbers based on their types

Suppose x and y are of the same type and can be either Boolean, Int, or Double. Here is the function I want to write:
f(x, y) =
- if x == Boolean ==> !x
- if x == Integer or x == Double ==> x+ y
One way of doing this can be the following. I was wondering if anyone has a better ideas on this.
def fun[T](x: T, y: T): T {
x match {
case xP: Boolean => !xP
case xP: Double => y match { case yP: Double => xP + yP }
case xP: Int => y match { case yP: Int => xP + yP }
}
}
The reason I am not happy with this is that x and y have the same type. I shouldn't need two match-cases; right?
Two other things:
Is it enough to just set [T <: Int, Double, Boolean] in order to restrict the type to only three types?
The output type needs to be again T.
This is precisely the kind of problem that type classes are designed to solve. In your case you could write something like this:
trait Add[A] {
def apply(a: A, b: A): A
}
object Add {
implicit val booleanAdd: Add[Boolean] = new Add[Boolean] {
def apply(a: Boolean, b: Boolean): Boolean = !a
}
implicit def numericAdd[A: Numeric]: Add[A] = new Add[A] {
def apply(a: A, b: A): A = implicitly[Numeric[A]].plus(a, b)
}
}
A value of type Add[X] describes how to add two values of type X. You put implicit "instances" of type Add[X] in scope for every type X that you want to be able to perform this operation on. In this case I've provided instances for Boolean and any type that has an instance of scala.math.Numeric (a type class that's provided by the standard library). If you only wanted instances for Int and Double, you could simply leave out numericAdd and write your own Add[Int] and Add[Double] instances.
You'd write your fun like this:
def fun[T: Add](x: T, y: T) = implicitly[Add[T]].apply(x, y)
And use it like this:
scala> fun(true, false)
res0: Boolean = false
scala> fun(1, 2)
res1: Int = 3
scala> fun(0.01, 1.01)
res2: Double = 1.02
This has the very significant advantage of not blowing up at runtime on types that you haven't defined the operation for. Instead of crashing your program with a MatchError exception when you pass e.g. two strings to fun, you get a nice compilation failure:
scala> fun("a", "b")
<console>:14: error: could not find implicit value for evidence parameter of type Add[String]
fun("a", "b")
^
In general "type case" matching (i.e. matches that look like case x: X => ...) are a bad idea in Scala, and there's almost always a better solution. Often it'll involve type classes.
If you want a generic function for summing numbers, you can make a trait Summable[A] with implicit conversions from the numbers you want to Summable. These conversions can be implicit methods or they can be methods in implicit objects, latter being shown below.
trait Summable[A] {
def +(a: A, b: A): A
}
object Summable {
implicit object SummableBoolean extends Summable[Boolean] {
override def +(a: Boolean, b: Boolean) = !a
}
implicit object SummableInt extends Summable[Int] {
override def +(a: Int, b: Int) = a + b
}
implicit object SummableDouble extends Summable[Double] {
override def +(a: Double, b: Double) = a + b
}
}
def fun[A](a: A, b: A)(implicit ev: Summable[A]) =
ev.+(a, b)
val res1 = fun(true, true) // returns false
val res2 = fun(1, 3) // returns 4
val res3 = fun(1.5, 4.3) // returns "5.8"
This is called a type class pattern. I included the boolean case because you asked for it, but I strongly believe that it has no place in a function which sums elements. One nice rule to follow is to have each function do one thing and one thing only. Then you can easily compose them into bigger functions. Inverting boolean has no place in a function that sums its arguments.
First of all, your example is syntactically wrong (missing case in match). A simple and shorter way I can figure now is something like this:
def fun[T <: AnyVal](x: T, y: T) = {
x match {
case xP: Boolean => !xP
case xP: Double => xP + y.asInstanceOf[Double]
case xP: Int => xP + y.asInstanceOf[Int]
}
}
fun(1, 2) // res0: AnyVal = 3
fun(2.5, 2.6) // res1: AnyVal = 5.1
fun(true, false) // res2: AnyVal = false

scala's spire framework : I am unable to operate on a group

I try to use spire, a math framework, but I have an error message:
import spire.algebra._
import spire.implicits._
trait AbGroup[A] extends Group[A]
final class Rationnel_Quadratique(val n1: Int = 2)(val coef: (Int, Int)) {
override def toString = {
coef match {
case (c, i) =>
s"$c + $i√$n"
}
}
def a() = coef._1
def b() = coef._2
def n() = n1
}
object Rationnel_Quadratique {
def apply(coef: (Int, Int),n: Int = 2)= {
new Rationnel_Quadratique(n)(coef)
}
}
object AbGroup {
implicit object RQAbGroup extends AbGroup[Rationnel_Quadratique] {
def +(a: Rationnel_Quadratique, b: Rationnel_Quadratique): Rationnel_Quadratique = Rationnel_Quadratique(coef=(a.a() + b.a(), a.b() + b.b()))
def inverse(a: Rationnel_Quadratique): Rationnel_Quadratique = Rationnel_Quadratique((-a.a(), -a.b()))
def id: Rationnel_Quadratique = Rationnel_Quadratique((0, 0))
}
}
object euler66_2 extends App {
val c = Rationnel_Quadratique((1, 2))
val d = Rationnel_Quadratique((3, 4))
val e = c + d
println(e)
}
the program is expected to add 1+2√2 and 3+4√2, but instead I have this error:
could not find implicit value for evidence parameter of type spire.algebra.AdditiveSemigroup[Rationnel_Quadratique]
val e = c + d
^
I think there is something essential I have missed (usage of implicits?)
It looks like you are not using Spire correctly.
Spire already has an AbGroup type, so you should be using that instead of redefining your own. Here's an example using a simple type I created called X.
import spire.implicits._
import spire.algebra._
case class X(n: BigInt)
object X {
implicit object XAbGroup extends AbGroup[X] {
def id: X = X(BigInt(0))
def op(lhs: X, rhs: X): X = X(lhs.n + rhs.n)
def inverse(lhs: X): X = X(-lhs.n)
}
}
def test(a: X, b: X): X = a |+| b
Note that with groups (as well as semigroups and monoids) you'd use |+| rather than +. To get plus, you'll want to define something with an AdditiveSemigroup (e.g. Semiring, or Ring, or Field or something).
You'll also use .inverse and |-| instead of unary and binary - if that makes sense.
Looking at your code, I am also not sure your actual number type is right. What will happen if I want to add two numbers with different values for n?
Anyway, hope this clears things up for you a bit.
EDIT: Since it seems like you're also getting hung up on Scala syntax, let me try to sketch a few designs that might work. First, there's always a more general solution:
import spire.implicits._
import spire.algebra._
import spire.math._
case class RQ(m: Map[Natural, SafeLong]) {
override def toString: String = m.map {
case (k, v) => if (k == 1) s"$v" else s"$v√$k" }.mkString(" + ")
}
object RQ {
implicit def abgroup[R <: Radical](implicit r: R): AbGroup[RQ] =
new AbGroup[RQ] {
def id: RQ = RQ(Map.empty)
def op(lhs: RQ, rhs: RQ): RQ = RQ(lhs.m + rhs.m)
def inverse(lhs: RQ): RQ = RQ(-lhs.m)
}
}
object Test {
def main(args: Array[String]) {
implicit val radical = _2
val x = RQ(Map(Natural(1) -> 1, Natural(2) -> 2))
val y = RQ(Map(Natural(1) -> 3, Natural(2) -> 4))
println(x)
println(y)
println(x |+| y)
}
}
This allows you to add different roots together without problem, at the cost of some indirection. You could also stick more closely to your design with something like this:
import spire.implicits._
import spire.algebra._
abstract class Radical(val n: Int) { override def toString: String = n.toString }
case object _2 extends Radical(2)
case object _3 extends Radical(3)
case class RQ[R <: Radical](a: Int, b: Int)(implicit r: R) {
override def toString: String = s"$a + $b√$r"
}
object RQ {
implicit def abgroup[R <: Radical](implicit r: R): AbGroup[RQ[R]] =
new AbGroup[RQ[R]] {
def id: RQ[R] = RQ[R](0, 0)
def op(lhs: RQ[R], rhs: RQ[R]): RQ[R] = RQ[R](lhs.a + rhs.a, lhs.b + rhs.b)
def inverse(lhs: RQ[R]): RQ[R] = RQ[R](-lhs.a, -lhs.b)
}
}
object Test {
def main(args: Array[String]) {
implicit val radical = _2
val x = RQ[_2.type](1, 2)
val y = RQ[_2.type](3, 4)
println(x)
println(y)
println(x |+| y)
}
}
This approach creates a fake type to represent whatever radical you are using (e.g. √2) and parameterizes QR on that type. This way you can be sure that no one will try to do additions that are invalid.
Hopefully one of these approaches will work for you.

Where do you split long Scala function signatures?

A definition like
def foo(x: Int) = x + 1
is nice and short and looks pretty, but when the signature itself gets uncomfortably long,
def foo[T <: Token[T]](x: ArrayBuffer[T], y: T => ArrayBuffer[() => T]): (T, T, BigDecimal) = {
// ...
}
I don't know where to split it. I find all of the following to look awkward:
def foo(
x: Int,
y: Int
): Int = {
// ...
}
def foo(
x: Int,
y: Int
): Int =
{
// ...
}
def foo(
x: Int,
y: Int
): Int
= {
// ...
}
def foo(
x: Int,
y: Int
):
Int = {
// ...
}
But, given that I'm going to have to get used to one of these, which will cause the least annoyance to my teammates?
The Scala style guide has nothing to say on this. In fact it recommends using methods with fewer parameters :-).
For function invocations it does recommend splitting so that each subsequent line aligns with the first parenthesis:
foo(someVeryLongFieldName,
andAnotherVeryLongFieldName,
"this is a string",
3.1415)
Personally in your case I would split according to a 'keep like things together' rule:
def foo[T <: Token[T]]
(x: ArrayBuffer[T], y: T => ArrayBuffer[() => T])
: (T, T, BigDecimal) = {
// ...
}
So the parameters are on one line, the return type is on a single line and the type restriction is on a single line.
In Haskell, long type signatures are often written in this fashion:
someFunc :: (Some Constraints Go Here)
=> Really Long Arg1 Type
-> Really Long Arg2 Type
-> Really Long Result Type
somefunc x y = ...
To translate this Haskellism into Scala,
def foo [ T <: Token[T] ]
( x : ArrayBuffer[T]
, y : T => ArrayBuffer[() => T]
) : (T, T, BigDecimal) = {
// ...
}
That's how I would do it. Not sure how kosher it is with the Scala community.