dvigal
dvigal

Reputation: 165

Structural type

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

Answers (3)

user1911636
user1911636

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

OscarRyz
OscarRyz

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

Andrzej Doyle
Andrzej Doyle

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

Related Questions