0

I am currently writing a generic function to execute Dispatch async requests, but I can't access generic type in Dispatch handler:

private def execQuery[MessageType](query : Req, errorMsg : String)
{
    Http(query OK as.String).either
        .onSuccess
    {
        case Left(error) => println(errorMsg)
        case Right(json) => println( new MessageType(json) ) // error here
    }
}

I have an error on new MessageType : "Cannot resolve symbol MessageType" in "new MessageType(json)". Can you help me ?

Thank you in advance

Victor

EDIT : I have found an other interesting way here http://www.brentsowers.com/2011/11/writing-generic-functions-that-take.html. You have to use the manifest feature :

class DynamicTestClass() {
    def output() {
        println("Hello from a dynamically sent class")
    }
}

def testFunc[T : Manifest]() : T = {
    manifest[T].erasure.newInstance().asInstanceOf[T]
}
val dynamicTestClassInstance = testFunc[DynamicTestClass]()
dynamicTestClassInstance.output()

It seems to work !

vhiairrassary
  • 354
  • 1
  • 2
  • 12

1 Answers1

1

You can't do

def mustMakeA[A](b:String):A = new A(b)

in scala.

A few practical reason. How is scalac supposed to know if A has public constructors and its argument?

However you can use a smarter design, for example, a type class that "knows" how to construct the parameter:

class Message(val value:String)

trait Constructor[A] {
   def cons(b:String) 
}

implicit class MessageHasConstructor(m:Message) extends Constructor[Message] {
   def cons(b:String) = new Message(b)
}

Et voilà, now we rewrite our mustMakeA as:

def mustMakeA[A:Constructor](b:String):A = implicitly[Constructor[A]].cons(b)

mustMakeA[Message]("Example") // would give us a `new Message("Example")`

Btw, I didn't test the code, so it might require some tweaking.

pedrofurla
  • 12,763
  • 1
  • 38
  • 49
  • French with accent, +1. `implicitly[Cons[A]]`, right? – som-snytt Apr 22 '14 at 10:37
  • Thank you, but your example need to add bloat code :/ See my edit, the Manifest feature seems to be the correct way to handle this. – vhiairrassary Apr 22 '14 at 12:15
  • Bloat of code? In that case I need you to define 'correct'. – pedrofurla Apr 22 '14 at 19:20
  • @som-snytt, oui, français seulement avec des accents! :) Btw, ops, you are right. – pedrofurla Apr 22 '14 at 19:21
  • Bloat of code? In that case I need you to define 'correct'. If you exercise your creativity a little bit, or if it's the case, actually learn Scala you will see that 'Manifest's are at best a patch-work solution for your problem. Type classes not only give a solution for one case, the example can be extended to all cases of constructors. – pedrofurla Apr 22 '14 at 19:28
  • @pedrofurla : yes I know introspection is not the best answer, but I come from c++ where I can instanciate generic type without any hack (introspection) nor with more than one line (what I called bloat code, sorry for the expression :/) – vhiairrassary Apr 22 '14 at 19:53
  • @pedrofurla : mais je suis d'accord que votre approche est sûrement bien meilleure, j'ai seulement proposé une autre façon de faire. J'aurais pas dû être aussi catégorique sur le "correct" – vhiairrassary Apr 22 '14 at 19:59