0

edit Simplified the example. Added more detail.

What I'd like is to do is compose a class with a method. The class has a type parameter of the form A[B], where A and B are abstract types (generic parameters), and its methods can work with objects of types A or B, or other types composed from A or B. For example, the class might have a method that takes an A[B] type object as a parameter, and return a B type object.

This kind of pattern is extremely common in say, the C++ standard template library.

Is this possible in scala?

In my example below, within ListDoer, A is the abstract type name ListT and B the abstract typename TElement. Later, I try to provide the concrete types, ListT[TElement] = MyList[Double]

class ListDoer[ ListT[TElement] ]
{
  // Processes abstract list type.                 
  def doIt( list:ListT[TElement] ) : TElement = { list.get(0) }   // TElement not found

  // Attempt 2:
  type L=ListT[TElement]               // TElement not found
  def doIt2( list:L ) : TElement ={ list.get(0) }   // TElement not found
}

// More concrete list type
class MyList[TElement]
{
   var None: TElement = _                         
   def get(i:Int): TElement = None   // placeholder               
   def put(i:Int, value:TElement): Unit = { }
}

// MyList[Double] is the concrete list type that doIt should take as a parameter
val doer2 = new ListDoer[ MyList[Double] ]   // MyList[Double] takes no parameters, expected one

val list1 = new MyList[Double]
doer2.doIt( list1 )         // Process list1. Should return list1.get(0)   

list.get(0) is a placeholder implementation for this example.

ListDoer class should not require any external types other than those provided as type parameters. (e.g. it should not be tied to a particular implementation of a list, or interfaces specified in any particular collections library). However, the above code is going to require that ListT[ElementT] has a method: get(Int):ElementT and cause ListDoer to fail to be instantiated is this is not met.

The above code looks reasonable to me (coming from a C++ background), but fails to compile in two places:

  • scala can't see the name TElement anywhere within ListDoer. This make it hard to make methods that takes or returns a TElement

  • the ListDoer cannot be instantiated

It this kind of nested use of generics permitted in scala?

3
  • If you tell what problems are you facing and what you want out of this code maybe somebody will be able to help. Commented Aug 12, 2013 at 22:55
  • 2
    This is an extremely vague question without much in the way of a goal, making it very difficult to answer. Commented Aug 12, 2013 at 23:12
  • Thanks -- have tidied the question up. More detail. Commented Aug 13, 2013 at 1:42

1 Answer 1

2
object XXX {

     class MyList[T] {
          var None: T = _
          def get(k: Int): T = None // placeholder               
          def put(k: Int, v: T): Unit = {}
     }

     class ListDoer[T] {

          // this defines the "wrapper" type 
          // which requires only get method to be there
          type W[T] = { def get(k: Int): T } 

          def doIt(list: W[T]): T = { 
               return null.asInstanceOf[T]
          } 
     }

     type L = Double
     val doer1 = new ListDoer[L] // L takes no parameters, expected one 
     val doer2 = new ListDoer[Double] // L takes no parameters, expected one

     val list1 = new MyList[Double]
     val list2 = List[L]()
     doer1.doIt(list1)

}
Sign up to request clarification or add additional context in comments.

2 Comments

In this case ListDoer has the constraint that doIt only accepts objects of types T. Isn't it possible to make it more generic so that it accepts types of the form A[B]?
Sorry -- just realized by last comment was wrong. In your solution, ListDoer requires a List[T]. What I'd like to do is require A[B] where A = type { get(Int):B } -- that is, A is ANY type having the method get(Int):B.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.