This page is no longer maintained — Please continue to the home page at www.scala-lang.org

typing issues

3 replies
vpalle
Joined: 2008-09-02,
User offline. Last seen 2 years 32 weeks ago.

Anyway to resolve the following typing issues? :

type arguments [patterns.ObserverExample.SubjectSensor] do not conform to
trait Obs's type parameter bounds
[T <: patterns.ObserverExample.Sub[patterns.ObserverExample.Obs]]

type arguments [patterns.ObserverExample.ObserverDisplay] do not conform to
trait Sub's type parameter
bounds [T <: patterns.ObserverExample.Obs[patterns.ObserverExample.Sub[T]]]

class Sensor(aLabel:String) {
val label:String = aLabel
var value:Double = _
def changeValue(v: Double) = {
value = v
}
}

class Display {
def show(s: String) = println(s)
}

trait Obs[T <: Sub[Obs]]{
def notify(s:T):Unit
}

trait Sub[T <: Obs[Sub[T]]] {
protected var observers: List[T] = List()
def subscribe(obs: T) = observers = obs :: observers
def unsubscribe(obs: T) = observers = observers - obs

// How can we type this!?
def publish = for (obs <- observers) obs.notify(this)
}

trait ObserverDisplay extends Display with Obs[SubjectSensor]{
override def notify(s: Sensor):Unit = {
show(s.label + " has value " + s.value)
}
}

trait SubjectSensor extends Sensor with Sub[ObserverDisplay]{
abstract override def changeValue(v:Double) = { super.changeValue(v);
publish }
}

vpalle
Joined: 2008-09-02,
User offline. Last seen 2 years 32 weeks ago.
Re: typing issues

Here is another solution, can we get rid of the cast in publish in trait Sub?

class Sensor(aLabel:String) {
val label:String = aLabel
var value:Double = _
def changeValue(v: Double) = {
value = v
}
}

class Display {
def show(s: String) = println(s)
}

trait Obs {
type T <: Sub
def notify(s:T):Unit
}

trait Sub {
type O <: Obs

protected var observers: List[O] = List()
def subscribe(obs: O) = observers = obs :: observers
def unsubscribe(obs: O) = observers = observers - obs

// Can we get rid of the cast?
def publish = for (obs <- observers)
obs.notify(this.asInstanceOf[obs.T])
}

trait ObserverDisplay extends Display with Obs{
type T = SubjectSensor
override def notify(s: SubjectSensor):Unit = {
show(s.label + " has value " + s.value)
}
}

trait SubjectSensor extends Sensor with Sub {
type O = ObserverDisplay
abstract override def changeValue(v:Double) = { super.changeValue(v);
publish }
}

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: typing issues
Try this:

class Sensor(aLabel:String) {
  val label:String = aLabel
  var value:Double = _
  def changeValue(v: Double) = {
    value = v
  }
}

class Display  {
  def show(s: String) = println(s)
}

trait Obs[T] {
  def notify(s:T):Unit
}

trait Sub[T] {
  self: T =>
    private var observers: List[Obs[T]] = Nil
  def subscribe(obs: Obs[T]) = observers = obs :: observers
  def unsubscribe(obs: Obs[T]) = observers = observers - obs

  // Can we get rid of the cast?
  def publish = for (obs <- observers)
    obs.notify(this)
}

trait ObserverDisplay extends Display with Obs[Sensor] {
  def notify(s: SubjectSensor):Unit = {
    show(s.label + " has value " + s.value)
  }
}

trait SubjectSensor extends Sensor with Sub[Sensor] {
  abstract override def changeValue(v:Double) = {
    super.changeValue(v)
    publish
  }
}

The subscriber manager is managing subscriptions to a particular type.  All we have to do is make sure that Sub is only mixed into that type.  You can make the whole issue much simpler by not having an Obs trait at all.  Rather than having a trait with a single method, why not have the Sub trait take a function T => Unit as its parameter.  That way, you can pass in a function the defines what to do on change:

class Sensor(aLabel:String) {
  val label:String = aLabel
  var value:Double = _
  def changeValue(v: Double) = {
    value = v
  }
}

class Display  {
  def show(s: String) = println(s)
}

trait Sub[T] {
  self: T =>
    private var observers: List[T => Unit] = Nil
  def subscribe(obs: T => Unit) = observers = obs :: observers
  def unsubscribe(obs: T => Unit) = observers = observers - obs

  // Can we get rid of the cast?
  protected def publish = for (obs <- observers) obs(this)
}

trait SubjectSensor extends Sensor with Sub[Sensor] {
  abstract override def changeValue(v:Double) = {
    super.changeValue(v)
    publish
  }
}


Thanks,

David

On Thu, Jan 15, 2009 at 8:09 AM, vpalle <vpalle [at] daimi [dot] au [dot] dk> wrote:

Here is another solution, can we get rid of the cast in publish in trait Sub?

class Sensor(aLabel:String) {
   val label:String = aLabel
   var value:Double = _
   def changeValue(v: Double) = {
     value = v
   }
 }

  class Display  {
   def show(s: String) = println(s)
 }

trait Obs {
   type T <: Sub
   def notify(s:T):Unit
 }

 trait Sub {
   type O <: Obs

   protected var observers: List[O] = List()
   def subscribe(obs: O) = observers = obs :: observers
   def unsubscribe(obs: O) = observers = observers - obs

   // Can we get rid of the cast?
   def publish = for (obs <- observers)
obs.notify(this.asInstanceOf[obs.T])
 }

 trait ObserverDisplay extends Display with Obs{
   type T = SubjectSensor
   override def notify(s: SubjectSensor):Unit = {
     show(s.label + " has value " + s.value)
   }
  }

 trait SubjectSensor extends Sensor with Sub {
   type O = ObserverDisplay
   abstract override def changeValue(v:Double) = { super.changeValue(v);
publish }
 }
--
View this message in context: http://www.nabble.com/typing-issues-tp21480401p21480646.html
Sent from the Scala - User mailing list archive at Nabble.com.




--
Lift, the simply functional web framework http://liftweb.net
Collaborative Task Management http://much4.us
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
vpalle
Joined: 2008-09-02,
User offline. Last seen 2 years 32 weeks ago.
Re: typing issues

Thank you for the elegant solution.. :)

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland