Reputation: 165
I have found for self is very interesting a fact. For example i've wrote:
type A = { val st: Set[Any]
val start: Set[Any]
val Sigma : Set[Char]
def tr(f: (Tuple2[Any, Any])=>Boolean): Set[Any]
}
class Fon {
val st: Set[Any]
val start: Set[Any]
val Sigma : Set[Char]
def tr(f: (Tuple2[Any, Any])=>Boolean): Set[Any] = Set(out)
def out: String = "is just example"
}
val a: A = new Fon
a.tr(f(Tuple2('a',0)))
But if i will try do call a.out - i get an error, that the type A have not exist 'out' What happening to this, how this to work? Thanks.
Upvotes: 1
Views: 297
Reputation: 1
type A is an abstract class or trait. Its member variables and methods are abstract.
type A = {val st: Set[Any]
val start: Set[Any]
val Sigma: Set[Char]
def tr(f: (Tuple2[Any, Any]) => Boolean): Set[Any]
}
Fon is a concrete class, just implement type A all abstract member.
class Fon {
val st: Set[Any] = null
val start: Set[Any] = null
val Sigma: Set[Char] = null
def tr(f: (Tuple2[Any, Any]) => Boolean): Set[Any] = Set(out)
def out: String = "is just example"
}
So, you can define a variable, type is A ,and concrete instance is Fon
val a: A = new Fon
println(a.tr(_ => false)) // Set(is just example)
extra:
f: (Tuple2[Any, Any]) => Boolean
is a abstract higher-order function as a parameter,
so, if you want to call method tr, the a.tr(f(Tuple2('a',0)))
calling mode can not resolve symbol f.
f: (Tuple2[Any, Any]) => Boolean
just getting a parameter, and return boolean.
so (_ => false)
is a concrete implement.
Upvotes: 0
Reputation: 199205
Basically it allows you to use one object ( Fon
) as it was another ( A
) granted they have the same features.
Since out
is not a feature of A
the compiler doesn't let you proceed.
Upvotes: 1
Reputation: 103777
There is no such method as A.out
, because of how you've defined the A
type. Thus, when you try to call a method called out
on an object of type A
, the compiler correctly tells you that no such method exists.
This is not related to structural typing, by the way - if you had made A
a trait and had Fon
extend it, you'd run into exactly the same problems. Moreover, this is just how static typing systems work - the compiler can't guarantee that your code is typesafe so it won't compile it.
If you want to call the out
method, then you'll need to refer to that object via a Fon
variable:
val a: Fon = new Fon
println(a.out) // works fine, since a is guaranteed to be a Fon and thus have the method
Upvotes: 5