How to use Scala's singleton-object types?

I'm writing a class which serves as base class for a series of singleton objects. In each singleton objects, there will be vals representing certain properties, and I want to write a method which, for each singleton object, only accepts objects created by it.

So I have the following:

class Obj[M <: Maker]

class Maker {
  implicit val me: this.type = this
  def make[M <: Maker](implicit maker: M) = new Obj[M]
  def accept(obj: Obj[this.type]) = {...}
}

So far, so good. Then I want to declare one of these singleton objects:

object M extends Maker {
  val a = make
}

But then, if I try this:

M.accept(M.a)

then I get a compile-time error:

type mismatch; found : com.test.Obj[object com.test.M] required: com.test.Obj[com.test.M.type]

My questions:

  1. What's the type object com.test.M, and how is it different from com.test.M.type?
  2. How can I do this in a smarter way?

Answers


Get with the times, my good man! I fixed this over 24 hours ago. Next I expect to see velociraptors chasing dodos, furiously cracking their buggy whips while looking up stock quotes on their pointcast screensavers.

The commit in question is: http://lampsvn.epfl.ch/trac/scala/changeset/23622

// 1130.scala
class Obj[M <: Maker]

class Maker {
  implicit val me: this.type = this
  def make[M <: Maker](implicit maker: M) = new Obj[M]
  def accept(obj: Obj[this.type]) = ()
}

object M extends Maker {
  val a = make
}

object Test {
  def main(args: Array[String]): Unit = {
    M.accept(M.a)
  }
}

// too old
% /scala/inst/scala-2.9.0.r23619/bin/scalac ./1130.scala 
./1130.scala:15: error: type mismatch;
 found   : Obj[object M]
 required: Obj[M.type]
    M.accept(M.a)
               ^
one error found

// fresh enough
% /scala/inst/scala-2.9.0.r23624/bin/scalac ./1130.scala 
%

Need Your Help

Removing duplicate commits happend while changing git commit author details

git github

I wanted to change the details of committer of previous commits. Porblem is when I tried to change, I see duplicate commits with from both user name.

When should a class member be declared virtual (C#)/Overridable (VB.NET)?

c# .net vb.net

Why wouldn't I choose abstract? What are the limitations to declaring a class member virtual? Can only methods be declared virtual?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.