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

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.

Related

Using a double value in a Fractional[T] method

I have the following function which generates a Uniform distributed value between 2 bounds:
def Uniform(x: Bounded[Double], n: Int): Bounded[Double] = {
val y: Double = (x.upper - x.lower) * scala.util.Random.nextDouble() + x.lower
Bounded(y, x.bounds)
}
and Bounded is defined as follows:
trait Bounded[T] {
val underlying: T
val bounds: (T, T)
def lower: T = bounds._1
def upper: T = bounds._2
override def toString = underlying.toString + " <- [" + lower.toString + "," + upper.toString + "]"
}
object Bounded {
def apply[T : Numeric](x: T, _bounds: (T, T)): Bounded[T] = new Bounded[T] {
override val underlying: T = x
override val bounds: (T, T) = _bounds
}
}
However, I want Uniform to work on all Fractional[T] values so I wanted to add a context bound:
def Uniform[T : Fractional](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * scala.util.Random.nextDouble().asInstanceOf[T] + x.lower
Bounded(y, x.bounds)
}
This works swell when doing a Uniform[Double](x: Bounded[Double]), but the other ones are impossible and get a ClassCastException at runtime because they can not be casted. Is there a way to solve this?
I'd suggest defining a new type class that characterizes types that you can get random instances of:
import scala.util.Random
trait GetRandom[A] {
def next(): A
}
object GetRandom {
def instance[A](a: => A): GetRandom[A] = new GetRandom[A] {
def next(): A = a
}
implicit val doubleRandom: GetRandom[Double] = instance(Random.nextDouble())
implicit val floatRandom: GetRandom[Float] = instance(Random.nextFloat())
// Define any other instances here
}
Now you can write Uniform like this:
def Uniform[T: Fractional: GetRandom](x: Bounded[T], n: Int): Bounded[T] = {
import Numeric.Implicits._
val y: T = (x.upper - x.lower) * implicitly[GetRandom[T]].next() + x.lower
Bounded(y, x.bounds)
}
And use it like this:
scala> Uniform[Double](Bounded(2, (0, 4)), 1)
res15: Bounded[Double] = 1.5325899033654382 <- [0.0,4.0]
scala> Uniform[Float](Bounded(2, (0, 4)), 1)
res16: Bounded[Float] = 0.06786823 <- [0.0,4.0]
There are libraries like rng that provide a similar type class for you, but they tend to be focused on purely functional ways to work with random numbers, so if you want something simpler you're probably best off writing your own.

How to override predefined function in Scala?

I need to implement function to. I have the following working code:
object Main {
val m = 0
val km = 1
implicit def wrapM(v: Int) = new {
def m = v
}
implicit def wrapKm(v: Int) = new {
def km = v * 1000
}
implicit class toWrap(fromVal: Int) {
def too (value: Int): Double = {
if (value.equals(km)) {
fromVal / 1000.0
} else {
0
}
}
}
def main(args:Array[String])
{
println(53.m too km)
}
}
But there is one problem. I use too name, instead of to. If I rename it to to, then I get the error:
Error:(30, 16) type mismatch;
found : Int
required: ?{def to(x$1: ? >: Int): ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method intWrapper in class LowPriorityImplicits of type (x: Int)scala.runtime.RichInt
and method toWrap in object Main of type (fromVal: Int)Main.toWrap
are possible conversion functions from Int to ?{def to(x$1: ? >: Int): ?}
println(53.m to km)
^
It is due to the fact, that there is one other function to - scala.runtime.RichInt#to.
Scala does not allow define two implicits with same arguments set in one context....
But there is a way. You should work with different type in toWrap implicit , instead of standard scala Int.
Check sample below.
My idea is to implement method to for some wrapper class IntWrap instead of standard Int
case class IntWrap(v: Int) {
}
val m = 0
val km = 1
implicit def wrapM(v: Int) = new {
def m = IntWrap(v)
}
implicit def wrapKm(v: Int) = new {
def km = v * 1000
}
implicit class toWrap(fromVal: IntWrap) {
def to(value: Int): Double = {
if (value.equals(km)) {
fromVal.v / 1000.0
} else {
0
}
}
}
def main(args:Array[String])
{
println(53.m to km)
}

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.

Modelling of C++ concepts with Scala traits

There are some examples of using Scala traits like C++ concepts and Haskell type classes in paper «Type Classes as Objects and Implicits». I try to write something like InputIterator concept and find function in Scala:
concept InputIterator<typename Iter> {
typename value_type;
value_type operator*(Iter);
...
};
template<typename Iter, typename V>
requires InputIterator<Iter> && EqualityComparable<Iter::value_type, V>
Iter find(Iter first, Iter last, V v) {
while (first < last && *first != v)
++first;
return first;
}
I'm not sure I understand traits correctly. But still... There is InputIterator trait written in Scala (or more exactly — it's simplified analogue with methods used in find function):
trait InputIterator[Iter] {
type value_type
def <(a: Iter, b: Iter): Boolean
def ++(it: Iter): Unit
def *(it: Iter): value_type
}
EqualityComparable is clear:
trait EqualityComparable[S, T] {
def ==(s: S, t: T): Boolean
def !=(s: S, t: T): Boolean = !(s == t)
}
But what should we do with find? I would like to write something like this:
def find[Iter, V](first: Iter, last: Iter, x: V)(implicit iterator: InputIterator[Iter],
cmp: EqualityComparable[iterator.value_type, V]): Iter =
{
while (iterator.<(first, last) && cmp.!=(iterator.*(first), x))
iterator.++(first)
first
}
But it causes an error «illegal dependent method type». And I don't know how to «extract» abstract type value_type other way. So as a result I have got this code:
trait EqualityComparable[S, T] {
def ==(s: S, t: T): Boolean
def !=(s: S, t: T): Boolean = !(s == t)
}
trait InputIterator[Iter] {
type value_type
def <(a: Iter, b: Iter): Boolean
def ++(it: Iter): Unit
def *(it: Iter): value_type
}
trait VTInputIterator[Iter, VT] extends InputIterator[Iter] {
type value_type = VT
}
class ArrayListIterator[T](a: ArrayList[T], i: Int) {
val arr: ArrayList[T] = a
var ind: Int = i
def curr(): T = arr.get(ind)
def ++(): Unit = { ind += 1 }
override def toString() = "[" + ind.toString() + "]"
}
class InputIterArrList[T] extends VTInputIterator[ArrayListIterator[T], T]{
def <(a: ArrayListIterator[T], b: ArrayListIterator[T]) = {
if (a.arr == b.arr) a.ind < b.ind
else throw new IllegalArgumentException()
}
def ++(it: ArrayListIterator[T]): Unit = it.++()
def *(it: ArrayListIterator[T]) = it.curr()
}
object TestInputIterator extends Application{
def find[Iter, VT, V](first: Iter, last: Iter, x: V)(implicit iterator: VTInputIterator[Iter, VT],
cmp: EqualityComparable[VT, V]): Iter =
{
while (iterator.<(first, last) && cmp.!=(iterator.*(first), x))
iterator.++(first)
first
}
implicit object EqIntInt extends EqualityComparable[Int, Int] {
def ==(a: Int, b: Int): Boolean = { a == b }
}
implicit object inputIterArrListInt extends InputIterArrList[Int]{}
val len = 10;
var arr: ArrayList[Int] = new ArrayList(len);
for (i: Int <- 1 to len)
arr.add(i)
var arrFirst = new ArrayListIterator(arr, 0)
var arrLast = new ArrayListIterator(arr, len)
var r = find(arrFirst, arrLast, 7)
println(r)
}
Instead of abstract type we used type parameter VT in def find[Iter, VT, V].
So the question is: how it can be done better? And is it possible to use abstract type value_type without additional type parameter VT?
Change the signature of find to:
def find[Iter, V, II <: InputIterator[Iter]](first: Iter, last: Iter, x: V)(
implicit iterator: II, cmp: EqualityComparable[II#value_type, V]): Iter
That's probably what you want to express.
Note that your Scala code is really not the same as the C++ code. In C++ find uses Iter::value_type but in Scala you use InputIterator[Iter]#value_type.

New Instances of Decorated Instances

I have a set of decorator-traits (for simplicity here only trait T) mixing in classes (here subclasses of A).
trait T { def i: Int }
abstract class A
type AT = A with T
class B extends A
// class C extends A
// class D extends A
// ...
Now I have an instance a of e.g. class B which I handle as an instance of type AT (together with other A-subclass-AT-instances in a Seq[AT]).
val a: AT = new B with T { val i = 8 }
How can I generically decorate like this:
def toAT(a: A, i: Int): AT = {
// how to ???
}
An obvious solution I thought about is:
trait T { def i: Int }
abstract class A {
def asAT(i: Int): AT
}
class B extends A {
def asAT(ii: Int): AT = new B with T { val i = ii }
}
type AT = A with T
def toAT(a: A, i: Int): AT = a.asAT(i)
But I don´t want to pollute my classes B, C, ..., Z with a new method and there are other decorations, so for every decoration-combo I need a new method for all subclasses!
Is there a more generic way?
EDIT:
An example why I need the toAT method, but still with the obvious solution approach from above in terms of a redecorated method:
trait T { def b: Boolean}
type AT = A with T
abstract class A(val i: Int) {
def changedBy(x: Int): A
def redecorated(oldAT: AT): AT
}
class B(x: Int) extends A(x) {
def changedBy(x: Int): A = new B(i * x)
def redecorated(oldAT: AT): AT = new B(i) with T { val b = oldAT.b }
}
class C(x: Int) extends A(x) {
def changedBy(x: Int): A = new C(i * x * x)
def redecorated(oldAT: AT): AT = new C(i) with T { val b = oldAT.b }
}
val b = new B(1) with T { val b = true }
val c = new C(1) with T { val b = false }
val x = 8
val res: Seq[AT] = Seq(b,c) map { at => at.changedBy(x).redecorated(at) }
Basically, you can't do it.
One alternative is to use the auto proxy plugin, by Kevin Wright. See also here and here for more information about it.