How to inherit the class of function**
This is code:
def A():
x = int(input('entrée x:'))
y = int(input('entrée x:'))
return x,y
class B:
def __init__(self):
self.add()
self.sup()
def add(self):
print(self.x + self.y)
def sup(self):
print(self.x - self.y)
A()
obj = B()
This is image
If I understood your question correctly, you want to use the tuple of values returned by your function A() to initialize attributes of your class B. First of all, I would modify B so that needed values can be passed at instantiation time:
class B:
def __init__(self, x, y):
self.x = x
self.y = y
self.add()
self.sup()
def add(self):
print(self.x + self.y)
def sup(self):
print(self.x - self.y)
You can now use your B class with whatever values you like:
B(1, 2)
B(45, 70)
And as a particular case, you can use your A function to ask for values interactively. You just have to use the * operator to expand the returned tuple to the expected argument list (see documentation)
B(*A())
Related
I have a case class.
case class A(x: Int)
I need to introduce another variable y which is dependent on x, say x/2.
Can I write something like this:
case class A(x: Int, y: Int = x/2)
If no what is the ideal solution?
case class A(x: Int) {
val y = x / 2
}
Example use:
val a = A(10)
a.x // 10
a.y // 5
Edit: if you must have y in your arguments then you can overload the apply function in a companion object:
case class A(x: Int, y: Int)
object A {
def apply(x: Int): A = new A(x, x / 2)
}
You can use this as before with A(10) but note that you will be able to call the default apply method with something like A(10, 11).
You can have two argument lists:
case class Foo(bar: Int)(val baz: Int = bar/2)
The downside is, you have to specify the second list, even when it is empty: Foo(2) does not work, has to be Foo(2)().
A bigger problem (same one as exists with the case class Foo(x: Int) { val y = x / 2 } approach) is that the second valisn't like the first one:
Foo(2)().toString // returns "Foo(2)"
Foo(2)().productArity // returns 1 (not 2)
Foo(2)().productIterator.toList // returns List(2)
You can still reference the second variable explicitly, like println(Foo(2)().baz) (prints 1), but none of the usual case-class stuff works. Even Foo(2)(1) == Foo(2)(4) will return true :(
So, your best option is overloading the apply method as suggested in the other answer.
If I have the following code:
trait MyTrait {
val x: Int
}
def f(_x: Int) = new MyTrait {
val x = _x
}
If I were to define my function as follows:
def f(x: Int) = new MyTrait {
val x = x
}
This would be incorrect as val x is just referring to itself. Is there a way I can avoid having to use a different name for 'x' when I want to refer to something in the outer scope?
You can, but only if the outer scope x is a member of enclosing type, not a method parameter or a local variable:
class MyOuter(val x: Int) {
def f() = new MyTrait {
val x = MyOuter.this.x
}
Not really: in the scope of MyTrait, x refers to the field. However, you have the option to wrap parameter into some other name before you enter that scope:
def f(x: Int) = {
val xn = x
new MyTrait {
val x = xn
}
}
Well, in this particular case, you could write something like this:
def f(x: Int) = {
class Foo(val x: Int = x) extends MyTrait
new Foo
}
Not sure what exactly it makes better over just renaming x to y though ...
I have a use case similar to the situation following:
trait A {
implicit val x = "hello"
}
class B {
// somehow bring x into scope here???
def run(x: Int)(implicit y: String) = y + x
}
println((new B).run(3))
I understand that I need to bring x defined in the trait in the implicit scope of B. I've already tried the following:
# attempt 1 #
class B extends A { .... } /// doesn't work
# attempt 2 #
class B extends A {
val x1 = implicitly[String] /// doesn't work either
def run(x: Int)(implicit y: String) = y + x
}
Please explain what am I missing here (or, point me to relevant theory topic which I can study, fairly new to scala).
The value of 'implicit y' will be resolved in your println-line where it is not available. You are making the variable implicitly available within the body of the class, but resolution of implicit String is not needed there.
Implicit isn't magic; if you can't reach the implicit variable explicitly then so can't the compiler.
What problem are you really trying to solve?
Wrap your whole code in a object and extend trait A in class B :
object P {
trait A {
implicit val x = "hello"
}
class B extends A {
def run(y: Int) = y + x
}
def f = println(new B().run(3))
}
Output :
scala> P.f
3hello
object P{
object P1{
class A{
//I want only classes/objects that extends A AND in the package P1 can access x
//It means, the modifier `protected` and the qualifier [P1] is combined with operator `AND`:
//protected AND [P1] means, x is:
// protected: not in subclass then not accessible
// AND [P1]: not in [P1] then not accessible
//protected OR [P1] means, x is:
// protected: not in subclass then not accessible
// OR [P1]: not in [P1] then not accessible
protected[P1] val x = 1
//Like `protected[this]`: y is protected AND [this]
//because y is accessible only in subclass AND in the same object
//(access to y in B2.f2 is permit but in B2.f3 is deny)
//(if protected[this] == protected OR [this] then protected[this] == protected :D)
protected[this] val y = 2
//Also, I don't know why the following code is valid
//(scalac 2.10.0 compile it!). Is this an error in scala compiler?
//But this strange modifiers combination is also not what I want!
private[P1] protected val z = 1
}
class B{
def f(a: A) = a.x + a.z //permit!
}
}
object P2{
class B2 extends P1.A{
def f = x + z //also permit!
def f2 = y //permit. OK
def f3(b: B2) = b.y //deny. OK
}
}
}
I know that protected[P1] modifier on x is same as java's protected. But, how to allow access to A.x only from classes/objects that extends A AND in the package P1?
EDIT:
#Randal ask: "Why do you care about the package constraint? What does that get you?"
I have a large project with a complex class. I split the class to several trait. But some members in some traits is intend to be used only in some (but not all) other sub-traits. So, I organize all traits that need the accessibility in one package. And the instantable class that need logic of those traits is put in another package. But the class need access to only some traits' members. Then I want only the needed members is visible to the class:
package p.base
private[base] trait A{
//x is intent to be used only in trait B and C
protected[base] val x = 1
}
private[base] trait B{this: A =>
//f is intent to be used only in trait C
protected[base] def f = x
//f2 will be used in global.D
def f2 = f
}
private[p] trait C extends B with A{...}
package p.global
class D extends p.base.C{
def g = f2
}
It's not possible using specialized access modifiers only. To get the compile time restrictions you could use a technique like this
object P {
object P1 {
class A {
#implicitNotFound(msg = "Only accessible when extending from A")
sealed trait OnlyA
protected[this] implicit object OnlyA extends OnlyA
private[P1] def x(implicit ev: A#OnlyA) = 1
private[P1] val z = 1
}
class B {
def f(a: A) = a.z + a.x // Will not work
}
class C extends A {
def f(a: A) = a.z + a.x // Works
}
}
object P2 {
class B2 extends P1.A {
def f = x // Will not work
def f(a: P1.A) = a.x + a.z // Will not work
}
}
}
You can protect the constructor with private[PkgName] and supply a factory to provide public creation so subclassing is confined to that package:
package pkg
...
class A private[pkg] { ...
}
object A {
def apply(): A = new A
}
...
I am implementing some lightweight mathematical vectors in scala. I would like to use the type system to check vector compatibility at compile time. For example, trying to add a vector of dimension 2 to another vector of dimension 3 should result in a compile error.
So far, I defined dimensions as case classes:
sealed trait Dim
case class One() extends Dim
case class Two() extends Dim
case class Three() extends Dim
case class Four() extends Dim
case class Five() extends Dim
And here is the vectors definition:
class Vec[D <: Dim](val values: Vector[Double]) {
def apply(i: Int) = values(i)
def *(k: Double) = new Vec[D]( values.map(_*k) )
def +(that: Vec[D]) = {
val newValues = ( values zip that.values ) map {
pair => pair._1 + pair._2
}
new Vec[D](newValues)
}
override lazy val toString = "Vec(" + values.mkString(", ") + ")"
}
This solution works well, however I have two concerns:
How can I add a dimension():Int method that returns the dimension (ie. 3 for a Vec[Three])?
How can I handle higher dimensions without declaring all the needed case classes in advance ?
PS: I know there are nice existing mathematical vector libs, I am just trying to improve my scala understanding.
My suggestions:
Peano Numbers by Apocalysp (link to part a, other parts follow)
Church Numerals by Jim McBeath
I's suggest something like this:
sealed abstract class Dim(val dimension:Int)
object Dim {
class One extends Dim(1)
class Two extends Dim(2)
class Three extends Dim(3)
implicit object One extends One
implicit object Two extends Two
implicit object Three extends Three
}
case class Vec[D <: Dim](values: Vector[Double])(implicit dim:D) {
require(values.size == dim.dimension)
def apply(i: Int) = values(i)
def *(k: Double) = Vec[D]( values.map(_*k) )
def +(that: Vec[D]) = Vec[D](
( values zip that.values ) map {
pair => pair._1 + pair._2
})
override lazy val toString = values.mkString("Vec(",", ",")")
}
Of course you can get only a runtime check on the vector length that way, but as others pointed already out you need something like Church numerals or other typelevel programming techniques to achieve compile time checks.
import Dim._
val a = Vec[Two](Vector(1.0,2.0))
val b = Vec[Two](Vector(1.0,3.0))
println(a + b)
//--> Vec(2.0, 5.0)
val c = Vec[Three](Vector(1.0,3.0))
//--> Exception in thread "main" java.lang.ExceptionInInitializerError
//--> at scalatest.vecTest.main(vecTest.scala)
//--> Caused by: java.lang.IllegalArgumentException: requirement failed
If you don't wish to go down the Peano route, you could always have your Vec be constructed with a D and then use the instance for determine the dimension via the Dim companion object. For instance:
object Dim {
def dimensionOf(d : Dim) = d match {
case One => 1
case Two => 2
case Three => 3
}
}
sealed trait Dim
I think for choice, you should be using case objects rather than case classes:
case object One extends Dim
case object Two extends Dim
Then on your vector, you might have to actually store the Dim:
object Vec {
def vec1 = new Vec[One](One)
def vec2 = new Vec[Two](Two)
def vec3 = new Vec[Three](Three)
}
class Vec[D <: Dim](d : D) {
def dimension : Int = Dim dimensionOf d
//etc