Scala, generic tuple

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












13














I have a generic method that can accept any tuple of any size, the only constraint is that the first element of this tuple should be of type MyClass.



Something like this:



trait MyTrait[T <: (MyClass, _*)] 
getMyClass(x: T): MyClass = x._1



I've tried this



trait MyTrait[T <: (MyClass, _) with (MyClass, _, _) with (MyClass, _, _) with ...] 
getMyClass(x: T): MyClass = x._1



but I get the error unboud wildcard type










share|improve this question


























    13














    I have a generic method that can accept any tuple of any size, the only constraint is that the first element of this tuple should be of type MyClass.



    Something like this:



    trait MyTrait[T <: (MyClass, _*)] 
    getMyClass(x: T): MyClass = x._1



    I've tried this



    trait MyTrait[T <: (MyClass, _) with (MyClass, _, _) with (MyClass, _, _) with ...] 
    getMyClass(x: T): MyClass = x._1



    but I get the error unboud wildcard type










    share|improve this question
























      13












      13








      13


      1





      I have a generic method that can accept any tuple of any size, the only constraint is that the first element of this tuple should be of type MyClass.



      Something like this:



      trait MyTrait[T <: (MyClass, _*)] 
      getMyClass(x: T): MyClass = x._1



      I've tried this



      trait MyTrait[T <: (MyClass, _) with (MyClass, _, _) with (MyClass, _, _) with ...] 
      getMyClass(x: T): MyClass = x._1



      but I get the error unboud wildcard type










      share|improve this question













      I have a generic method that can accept any tuple of any size, the only constraint is that the first element of this tuple should be of type MyClass.



      Something like this:



      trait MyTrait[T <: (MyClass, _*)] 
      getMyClass(x: T): MyClass = x._1



      I've tried this



      trait MyTrait[T <: (MyClass, _) with (MyClass, _, _) with (MyClass, _, _) with ...] 
      getMyClass(x: T): MyClass = x._1



      but I get the error unboud wildcard type







      scala generics






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Dec 12 at 9:18









      Gigitsu

      19212




      19212






















          7 Answers
          7






          active

          oldest

          votes


















          4














          It's a little bit unsafe but you can use Structural type in this case:



          trait MyTrait 
          def getMyClass(x: def _1: MyClass): MyClass = x._1






          share|improve this answer


















          • 2




            This is compound type or "structural type" which, unlike "Duck typing", has a clearly-defined meaning is Scala.
            – Tim
            Dec 12 at 10:25











          • @Tim, yes thank you I mean structural type.
            – mkUltra
            Dec 12 at 10:31






          • 1




            This was surprisingly simple.
            – Sarvesh Kumar Singh
            Dec 12 at 14:15










          • Just to strength constrain you may use Product def _1: MyClass , but it steel can accept case class with def _1
            – Yuriy
            Dec 13 at 1:30










          • This is very simple to use, thank you. Anyway I had to enable reflective call, am I right?
            – Gigitsu
            Dec 13 at 13:07


















          11














          If you want to do this without either boilerplate or runtime reflection, Shapeless is your best bet. You can use the IsComposite type class to put type-level constraints on the first element of a tuple:



          import shapeless.ops.tuple.IsComposite

          trait MustBeFirst

          class MyClass[P <: Product](p: P)(implicit ev: IsComposite[P] type H = MustBeFirst )
          def getMustBeFirst(x: P): MustBeFirst = ev.head(p)



          And then:



          scala> val good2 = (new MustBeFirst , "")
          good2: (MustBeFirst, String) = ($anon$1@7294acee,"")

          scala> val good3 = (new MustBeFirst , "", 123)
          good3: (MustBeFirst, String, Int) = ($anon$1@6eff9288,"",123)

          scala> val good4 = (new MustBeFirst , "", 'xyz, 123)
          good4: (MustBeFirst, String, Symbol, Int) = ($anon$1@108cdf99,"",'xyz,123)

          scala> val bad2 = ("abc", 123)
          bad2: (String, Int) = (abc,123)

          scala> new MyClass(good2)
          res0: MyClass[(MustBeFirst, String)] = MyClass@5297aa76

          scala> new MyClass(good3)
          res1: MyClass[(MustBeFirst, String, Int)] = MyClass@3f501844

          scala> new MyClass(good4)
          res2: MyClass[(MustBeFirst, String, Symbol, Int)] = MyClass@24e15478

          scala> new MyClass(bad2)
          <console>:15: error: could not find implicit value for parameter ev: shapeless.ops.tuple.IsComposite[(String, Int)]type H = MustBeFirst
          new MyClass(bad2)
          ^


          If you need to use a trait, you can put the ev (for "evidence") requirement inside the definition instead of in the constructor:



          trait MyTrait[P <: Product] 
          implicit def ev: IsComposite[P] type H = MustBeFirst



          Now any class instantiating MyTrait will have to provide evidence that P is a tuple with MustBeFirst as its first element.






          share|improve this answer






















          • Probably nitpicking, but I if read shapeless source correctly, IsComposite will also witness that the tuple is of size at least 2. It may be a relevant detail for the asker since tuples of size 1, however awkward, are a thing ^^
            – C4stor
            Dec 12 at 10:46










          • @C4stor Good point—I'll update the answer to clarify asap.
            – Travis Brown
            Dec 12 at 11:19






          • 1




            @C4stor IsComposite works for Tuple1, with tail type being Unit.
            – Oleg Pyzhcov
            Dec 12 at 12:19










          • Oh, interesting ! Shapeless is tricky :D
            – C4stor
            Dec 12 at 13:18






          • 1




            Altought I like this solution and shapeless in general, I don't know how to use this in my case. This is my actual use case: pastebin.com/yCKs0eiQ
            – Gigitsu
            Dec 13 at 13:02



















          2














          Scala can't use generic tuple with unknown size because Products don's inherit themeselfs. You can try to use Shapeless or Products from play json lib.






          share|improve this answer
















          • 1




            Can you clarify what "don't inherit themselves" means here? I don't see what that means or how it would help.
            – Travis Brown
            Dec 12 at 10:28










          • Hi :-) The asker didn't specify unknown size but rather any size, which is weaker. For example, shapeless HLists (as you relevantly suggest) are definitely not of unknown size since their size is known at compile time :-) As Travis Brown, I can't quite figure what you mean in this answer, clarifying would be very helpful :-)
            – C4stor
            Dec 12 at 10:49


















          0














          Because tuples of differing sizes are (almost) unrelated types, if you need the compiler to type-check the calls to getMyClass() then you might have to overload it.



          trait MyTrait 
          def getMyClass(x :(MyClass,_)) :MyClass = x._1
          def getMyClass(x :(MyClass,_,_)) :MyClass = x._1
          def getMyClass(x :(MyClass,_,_,_)) :MyClass = x._1
          def getMyClass(x :(MyClass,_,_,_,_)) :MyClass = x._1






          share|improve this answer




























            0














            You need to inherit your trait from Product, through which you can have productIterator, productArity and, productElement to handle the returned value. Here is an example



            case class MyClass()

            trait MyTrait[T <: Product]
            def getMyClass(x: T): Option[MyClass] =
            if(
            x.productIterator.hasNext
            &&
            x.productIterator.next().isInstanceOf[MyClass]
            )
            Some(x.productIterator.next().asInstanceOf[MyClass])
            else
            None



            case class Test() extends MyTrait[Product]


            And you can invoke like this



            Test().getMyClass((MyClass(), 1,3,4,5))
            //res1: Option[MyClass] = Some(MyClass())

            Test().getMyClass((1,3,4,5))
            //res2: Option[MyClass] = None


            Hope this helps you.






            share|improve this answer






























              -1














              As others said you can use shapeless:



              import shapeless.ops.tuple.IsComposite
              import shapeless.syntax.std.tuple._

              class MyClass(i : Int)
              def hello() = println(i)



              object Tup extends App

              def getMyClass[P <: Product](p: P)(implicit ev: IsComposite[P]): MyClass =
              if (p.head.isInstanceOf[MyClass]) p.head.asInstanceOf[MyClass] else throw new Exception()

              val x= (new MyClass(1),5,6)
              val y = (new MyClass(2),7)

              val c = getMyClass(x)
              val c1 = getMyClass(y)
              c.hello()
              c1.hello()

              val c2 = getMyClass((1,5,6,7)) // exception
              c2.hello()







              share|improve this answer




















              • This doesn't provide any type-safety—the failure happens at runtime, not compile-time. You're not actually doing anything with Shapeless here beyond restricting the tuple to have more than one element, which isn't explicitly a requirement, anyway.
                – Travis Brown
                Dec 12 at 11:34










              • @travis fair enough - though I shapeless is also used to get the first element from the tuple regardless of it and I understood that the question as 1. accept tuples of any size.2 get the MyClass from the first element from the tuple (which by the way your suggested solution does not actually do)
                – Arnon Rotem-Gal-Oz
                Dec 12 at 12:34










              • Why all the casting, then?
                – Travis Brown
                Dec 12 at 12:38










              • @TravisBrown, as I said you're right about that -, could have been done better (e.g. what you did) but it does actually answer the q (how to implement getMyClass(x: T): MyClass = x._1 which works) - your solution is missing a def getMyClass(p: P) : MyClass = p.head to actually answer the question (and be typesafe )
                – Arnon Rotem-Gal-Oz
                Dec 12 at 13:19


















              -1














              If you are looking for compile time guarantee then this is one of the use cases for
              Shapeless,



              You need to add Shapeless in your build.sbt,



              libraryDependencies ++= Seq("
              com.chuusai" %% "shapeless" % "2.3.3"
              )


              Now, you can use Shapeless to define a typesafe getter which comes with compile time guarantees,



              scala> import shapeless._
              // import shapeless._

              scala> import ops.tuple.IsComposite
              // import ops.tuple.IsComposite

              scala> import syntax.std.tuple._
              // import syntax.std.tuple._

              scala> case class Omg(omg: String)
              // defined class Omg

              scala> val myStringTuple = ("All is well", 42, "hope")
              // myStringTuple: (String, Int, String) = (All is well,42,hope)

              scala> val myOmgTuple = (Omg("All is well"), 42, "hope")
              // myOmgTuple: (Omg, Int, String) = (Omg(All is well),42,hope)


              Now if you want to enrich your tuples with a "first" getter with a specific type then,



              scala> implicit class GetterForProduct[B <: Product](b: B) 

              // defined class GetterForProduct

              scala> val myString = myStringTuple.getFirst[String]
              // myString: String = All is well

              scala> val myOmgError = myOmgTuple.getFirst[String]
              // <console>:24: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
              // val myOmgError = myOmgTuple.getFirst[String]
              // ^

              scala> val myOmg = myOmgTuple.getFirst[Omg]
              // myOmg: Omg = Omg(All is well


              If you don't need the implicit enrichment and are just looking for a way to "lock" the type in a getter and use it for corresponding types,



              scala> trait FirstGetterInProduct[A] 

              // defined trait FirstGetterInProduct

              scala> object firstGetterInProductForString extends FirstGetterInProduct[String]
              // defined object firstGetterInProductForString

              scala> object firstGetterInProductForOmg extends FirstGetterInProduct[Omg]
              // defined object firstGetterInProductForOmg

              // Right tuple with right getter,
              scala> val myString = firstGetterInProductForString.getFirst(myStringTuple)
              // myString: String = All is well

              // will fail at compile time for tuple with different type for first
              scala> val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
              // <console>:23: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
              // val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
              // ^

              scala> val myOmg = firstGetterInProductForOmg.getFirst(myOmgTuple)
              // myOmg: Omg = Omg(All is well)





              share|improve this answer






















              • What is the "compile time guarantee" here? The OP has requested that tuples of any length, but only with the 1st element of a specific type, be accepted. (Not my down-vote.)
                – jwvh
                Dec 12 at 11:52










              • @jwvh You are right. Fixed.
                – Sarvesh Kumar Singh
                Dec 12 at 14:08










              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "1"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53739656%2fscala-generic-tuple%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              7 Answers
              7






              active

              oldest

              votes








              7 Answers
              7






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              4














              It's a little bit unsafe but you can use Structural type in this case:



              trait MyTrait 
              def getMyClass(x: def _1: MyClass): MyClass = x._1






              share|improve this answer


















              • 2




                This is compound type or "structural type" which, unlike "Duck typing", has a clearly-defined meaning is Scala.
                – Tim
                Dec 12 at 10:25











              • @Tim, yes thank you I mean structural type.
                – mkUltra
                Dec 12 at 10:31






              • 1




                This was surprisingly simple.
                – Sarvesh Kumar Singh
                Dec 12 at 14:15










              • Just to strength constrain you may use Product def _1: MyClass , but it steel can accept case class with def _1
                – Yuriy
                Dec 13 at 1:30










              • This is very simple to use, thank you. Anyway I had to enable reflective call, am I right?
                – Gigitsu
                Dec 13 at 13:07















              4














              It's a little bit unsafe but you can use Structural type in this case:



              trait MyTrait 
              def getMyClass(x: def _1: MyClass): MyClass = x._1






              share|improve this answer


















              • 2




                This is compound type or "structural type" which, unlike "Duck typing", has a clearly-defined meaning is Scala.
                – Tim
                Dec 12 at 10:25











              • @Tim, yes thank you I mean structural type.
                – mkUltra
                Dec 12 at 10:31






              • 1




                This was surprisingly simple.
                – Sarvesh Kumar Singh
                Dec 12 at 14:15










              • Just to strength constrain you may use Product def _1: MyClass , but it steel can accept case class with def _1
                – Yuriy
                Dec 13 at 1:30










              • This is very simple to use, thank you. Anyway I had to enable reflective call, am I right?
                – Gigitsu
                Dec 13 at 13:07













              4












              4








              4






              It's a little bit unsafe but you can use Structural type in this case:



              trait MyTrait 
              def getMyClass(x: def _1: MyClass): MyClass = x._1






              share|improve this answer














              It's a little bit unsafe but you can use Structural type in this case:



              trait MyTrait 
              def getMyClass(x: def _1: MyClass): MyClass = x._1







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 12 at 10:31

























              answered Dec 12 at 10:09









              mkUltra

              580620




              580620







              • 2




                This is compound type or "structural type" which, unlike "Duck typing", has a clearly-defined meaning is Scala.
                – Tim
                Dec 12 at 10:25











              • @Tim, yes thank you I mean structural type.
                – mkUltra
                Dec 12 at 10:31






              • 1




                This was surprisingly simple.
                – Sarvesh Kumar Singh
                Dec 12 at 14:15










              • Just to strength constrain you may use Product def _1: MyClass , but it steel can accept case class with def _1
                – Yuriy
                Dec 13 at 1:30










              • This is very simple to use, thank you. Anyway I had to enable reflective call, am I right?
                – Gigitsu
                Dec 13 at 13:07












              • 2




                This is compound type or "structural type" which, unlike "Duck typing", has a clearly-defined meaning is Scala.
                – Tim
                Dec 12 at 10:25











              • @Tim, yes thank you I mean structural type.
                – mkUltra
                Dec 12 at 10:31






              • 1




                This was surprisingly simple.
                – Sarvesh Kumar Singh
                Dec 12 at 14:15










              • Just to strength constrain you may use Product def _1: MyClass , but it steel can accept case class with def _1
                – Yuriy
                Dec 13 at 1:30










              • This is very simple to use, thank you. Anyway I had to enable reflective call, am I right?
                – Gigitsu
                Dec 13 at 13:07







              2




              2




              This is compound type or "structural type" which, unlike "Duck typing", has a clearly-defined meaning is Scala.
              – Tim
              Dec 12 at 10:25





              This is compound type or "structural type" which, unlike "Duck typing", has a clearly-defined meaning is Scala.
              – Tim
              Dec 12 at 10:25













              @Tim, yes thank you I mean structural type.
              – mkUltra
              Dec 12 at 10:31




              @Tim, yes thank you I mean structural type.
              – mkUltra
              Dec 12 at 10:31




              1




              1




              This was surprisingly simple.
              – Sarvesh Kumar Singh
              Dec 12 at 14:15




              This was surprisingly simple.
              – Sarvesh Kumar Singh
              Dec 12 at 14:15












              Just to strength constrain you may use Product def _1: MyClass , but it steel can accept case class with def _1
              – Yuriy
              Dec 13 at 1:30




              Just to strength constrain you may use Product def _1: MyClass , but it steel can accept case class with def _1
              – Yuriy
              Dec 13 at 1:30












              This is very simple to use, thank you. Anyway I had to enable reflective call, am I right?
              – Gigitsu
              Dec 13 at 13:07




              This is very simple to use, thank you. Anyway I had to enable reflective call, am I right?
              – Gigitsu
              Dec 13 at 13:07













              11














              If you want to do this without either boilerplate or runtime reflection, Shapeless is your best bet. You can use the IsComposite type class to put type-level constraints on the first element of a tuple:



              import shapeless.ops.tuple.IsComposite

              trait MustBeFirst

              class MyClass[P <: Product](p: P)(implicit ev: IsComposite[P] type H = MustBeFirst )
              def getMustBeFirst(x: P): MustBeFirst = ev.head(p)



              And then:



              scala> val good2 = (new MustBeFirst , "")
              good2: (MustBeFirst, String) = ($anon$1@7294acee,"")

              scala> val good3 = (new MustBeFirst , "", 123)
              good3: (MustBeFirst, String, Int) = ($anon$1@6eff9288,"",123)

              scala> val good4 = (new MustBeFirst , "", 'xyz, 123)
              good4: (MustBeFirst, String, Symbol, Int) = ($anon$1@108cdf99,"",'xyz,123)

              scala> val bad2 = ("abc", 123)
              bad2: (String, Int) = (abc,123)

              scala> new MyClass(good2)
              res0: MyClass[(MustBeFirst, String)] = MyClass@5297aa76

              scala> new MyClass(good3)
              res1: MyClass[(MustBeFirst, String, Int)] = MyClass@3f501844

              scala> new MyClass(good4)
              res2: MyClass[(MustBeFirst, String, Symbol, Int)] = MyClass@24e15478

              scala> new MyClass(bad2)
              <console>:15: error: could not find implicit value for parameter ev: shapeless.ops.tuple.IsComposite[(String, Int)]type H = MustBeFirst
              new MyClass(bad2)
              ^


              If you need to use a trait, you can put the ev (for "evidence") requirement inside the definition instead of in the constructor:



              trait MyTrait[P <: Product] 
              implicit def ev: IsComposite[P] type H = MustBeFirst



              Now any class instantiating MyTrait will have to provide evidence that P is a tuple with MustBeFirst as its first element.






              share|improve this answer






















              • Probably nitpicking, but I if read shapeless source correctly, IsComposite will also witness that the tuple is of size at least 2. It may be a relevant detail for the asker since tuples of size 1, however awkward, are a thing ^^
                – C4stor
                Dec 12 at 10:46










              • @C4stor Good point—I'll update the answer to clarify asap.
                – Travis Brown
                Dec 12 at 11:19






              • 1




                @C4stor IsComposite works for Tuple1, with tail type being Unit.
                – Oleg Pyzhcov
                Dec 12 at 12:19










              • Oh, interesting ! Shapeless is tricky :D
                – C4stor
                Dec 12 at 13:18






              • 1




                Altought I like this solution and shapeless in general, I don't know how to use this in my case. This is my actual use case: pastebin.com/yCKs0eiQ
                – Gigitsu
                Dec 13 at 13:02
















              11














              If you want to do this without either boilerplate or runtime reflection, Shapeless is your best bet. You can use the IsComposite type class to put type-level constraints on the first element of a tuple:



              import shapeless.ops.tuple.IsComposite

              trait MustBeFirst

              class MyClass[P <: Product](p: P)(implicit ev: IsComposite[P] type H = MustBeFirst )
              def getMustBeFirst(x: P): MustBeFirst = ev.head(p)



              And then:



              scala> val good2 = (new MustBeFirst , "")
              good2: (MustBeFirst, String) = ($anon$1@7294acee,"")

              scala> val good3 = (new MustBeFirst , "", 123)
              good3: (MustBeFirst, String, Int) = ($anon$1@6eff9288,"",123)

              scala> val good4 = (new MustBeFirst , "", 'xyz, 123)
              good4: (MustBeFirst, String, Symbol, Int) = ($anon$1@108cdf99,"",'xyz,123)

              scala> val bad2 = ("abc", 123)
              bad2: (String, Int) = (abc,123)

              scala> new MyClass(good2)
              res0: MyClass[(MustBeFirst, String)] = MyClass@5297aa76

              scala> new MyClass(good3)
              res1: MyClass[(MustBeFirst, String, Int)] = MyClass@3f501844

              scala> new MyClass(good4)
              res2: MyClass[(MustBeFirst, String, Symbol, Int)] = MyClass@24e15478

              scala> new MyClass(bad2)
              <console>:15: error: could not find implicit value for parameter ev: shapeless.ops.tuple.IsComposite[(String, Int)]type H = MustBeFirst
              new MyClass(bad2)
              ^


              If you need to use a trait, you can put the ev (for "evidence") requirement inside the definition instead of in the constructor:



              trait MyTrait[P <: Product] 
              implicit def ev: IsComposite[P] type H = MustBeFirst



              Now any class instantiating MyTrait will have to provide evidence that P is a tuple with MustBeFirst as its first element.






              share|improve this answer






















              • Probably nitpicking, but I if read shapeless source correctly, IsComposite will also witness that the tuple is of size at least 2. It may be a relevant detail for the asker since tuples of size 1, however awkward, are a thing ^^
                – C4stor
                Dec 12 at 10:46










              • @C4stor Good point—I'll update the answer to clarify asap.
                – Travis Brown
                Dec 12 at 11:19






              • 1




                @C4stor IsComposite works for Tuple1, with tail type being Unit.
                – Oleg Pyzhcov
                Dec 12 at 12:19










              • Oh, interesting ! Shapeless is tricky :D
                – C4stor
                Dec 12 at 13:18






              • 1




                Altought I like this solution and shapeless in general, I don't know how to use this in my case. This is my actual use case: pastebin.com/yCKs0eiQ
                – Gigitsu
                Dec 13 at 13:02














              11












              11








              11






              If you want to do this without either boilerplate or runtime reflection, Shapeless is your best bet. You can use the IsComposite type class to put type-level constraints on the first element of a tuple:



              import shapeless.ops.tuple.IsComposite

              trait MustBeFirst

              class MyClass[P <: Product](p: P)(implicit ev: IsComposite[P] type H = MustBeFirst )
              def getMustBeFirst(x: P): MustBeFirst = ev.head(p)



              And then:



              scala> val good2 = (new MustBeFirst , "")
              good2: (MustBeFirst, String) = ($anon$1@7294acee,"")

              scala> val good3 = (new MustBeFirst , "", 123)
              good3: (MustBeFirst, String, Int) = ($anon$1@6eff9288,"",123)

              scala> val good4 = (new MustBeFirst , "", 'xyz, 123)
              good4: (MustBeFirst, String, Symbol, Int) = ($anon$1@108cdf99,"",'xyz,123)

              scala> val bad2 = ("abc", 123)
              bad2: (String, Int) = (abc,123)

              scala> new MyClass(good2)
              res0: MyClass[(MustBeFirst, String)] = MyClass@5297aa76

              scala> new MyClass(good3)
              res1: MyClass[(MustBeFirst, String, Int)] = MyClass@3f501844

              scala> new MyClass(good4)
              res2: MyClass[(MustBeFirst, String, Symbol, Int)] = MyClass@24e15478

              scala> new MyClass(bad2)
              <console>:15: error: could not find implicit value for parameter ev: shapeless.ops.tuple.IsComposite[(String, Int)]type H = MustBeFirst
              new MyClass(bad2)
              ^


              If you need to use a trait, you can put the ev (for "evidence") requirement inside the definition instead of in the constructor:



              trait MyTrait[P <: Product] 
              implicit def ev: IsComposite[P] type H = MustBeFirst



              Now any class instantiating MyTrait will have to provide evidence that P is a tuple with MustBeFirst as its first element.






              share|improve this answer














              If you want to do this without either boilerplate or runtime reflection, Shapeless is your best bet. You can use the IsComposite type class to put type-level constraints on the first element of a tuple:



              import shapeless.ops.tuple.IsComposite

              trait MustBeFirst

              class MyClass[P <: Product](p: P)(implicit ev: IsComposite[P] type H = MustBeFirst )
              def getMustBeFirst(x: P): MustBeFirst = ev.head(p)



              And then:



              scala> val good2 = (new MustBeFirst , "")
              good2: (MustBeFirst, String) = ($anon$1@7294acee,"")

              scala> val good3 = (new MustBeFirst , "", 123)
              good3: (MustBeFirst, String, Int) = ($anon$1@6eff9288,"",123)

              scala> val good4 = (new MustBeFirst , "", 'xyz, 123)
              good4: (MustBeFirst, String, Symbol, Int) = ($anon$1@108cdf99,"",'xyz,123)

              scala> val bad2 = ("abc", 123)
              bad2: (String, Int) = (abc,123)

              scala> new MyClass(good2)
              res0: MyClass[(MustBeFirst, String)] = MyClass@5297aa76

              scala> new MyClass(good3)
              res1: MyClass[(MustBeFirst, String, Int)] = MyClass@3f501844

              scala> new MyClass(good4)
              res2: MyClass[(MustBeFirst, String, Symbol, Int)] = MyClass@24e15478

              scala> new MyClass(bad2)
              <console>:15: error: could not find implicit value for parameter ev: shapeless.ops.tuple.IsComposite[(String, Int)]type H = MustBeFirst
              new MyClass(bad2)
              ^


              If you need to use a trait, you can put the ev (for "evidence") requirement inside the definition instead of in the constructor:



              trait MyTrait[P <: Product] 
              implicit def ev: IsComposite[P] type H = MustBeFirst



              Now any class instantiating MyTrait will have to provide evidence that P is a tuple with MustBeFirst as its first element.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 12 at 12:38

























              answered Dec 12 at 10:17









              Travis Brown

              112k9283531




              112k9283531











              • Probably nitpicking, but I if read shapeless source correctly, IsComposite will also witness that the tuple is of size at least 2. It may be a relevant detail for the asker since tuples of size 1, however awkward, are a thing ^^
                – C4stor
                Dec 12 at 10:46










              • @C4stor Good point—I'll update the answer to clarify asap.
                – Travis Brown
                Dec 12 at 11:19






              • 1




                @C4stor IsComposite works for Tuple1, with tail type being Unit.
                – Oleg Pyzhcov
                Dec 12 at 12:19










              • Oh, interesting ! Shapeless is tricky :D
                – C4stor
                Dec 12 at 13:18






              • 1




                Altought I like this solution and shapeless in general, I don't know how to use this in my case. This is my actual use case: pastebin.com/yCKs0eiQ
                – Gigitsu
                Dec 13 at 13:02

















              • Probably nitpicking, but I if read shapeless source correctly, IsComposite will also witness that the tuple is of size at least 2. It may be a relevant detail for the asker since tuples of size 1, however awkward, are a thing ^^
                – C4stor
                Dec 12 at 10:46










              • @C4stor Good point—I'll update the answer to clarify asap.
                – Travis Brown
                Dec 12 at 11:19






              • 1




                @C4stor IsComposite works for Tuple1, with tail type being Unit.
                – Oleg Pyzhcov
                Dec 12 at 12:19










              • Oh, interesting ! Shapeless is tricky :D
                – C4stor
                Dec 12 at 13:18






              • 1




                Altought I like this solution and shapeless in general, I don't know how to use this in my case. This is my actual use case: pastebin.com/yCKs0eiQ
                – Gigitsu
                Dec 13 at 13:02
















              Probably nitpicking, but I if read shapeless source correctly, IsComposite will also witness that the tuple is of size at least 2. It may be a relevant detail for the asker since tuples of size 1, however awkward, are a thing ^^
              – C4stor
              Dec 12 at 10:46




              Probably nitpicking, but I if read shapeless source correctly, IsComposite will also witness that the tuple is of size at least 2. It may be a relevant detail for the asker since tuples of size 1, however awkward, are a thing ^^
              – C4stor
              Dec 12 at 10:46












              @C4stor Good point—I'll update the answer to clarify asap.
              – Travis Brown
              Dec 12 at 11:19




              @C4stor Good point—I'll update the answer to clarify asap.
              – Travis Brown
              Dec 12 at 11:19




              1




              1




              @C4stor IsComposite works for Tuple1, with tail type being Unit.
              – Oleg Pyzhcov
              Dec 12 at 12:19




              @C4stor IsComposite works for Tuple1, with tail type being Unit.
              – Oleg Pyzhcov
              Dec 12 at 12:19












              Oh, interesting ! Shapeless is tricky :D
              – C4stor
              Dec 12 at 13:18




              Oh, interesting ! Shapeless is tricky :D
              – C4stor
              Dec 12 at 13:18




              1




              1




              Altought I like this solution and shapeless in general, I don't know how to use this in my case. This is my actual use case: pastebin.com/yCKs0eiQ
              – Gigitsu
              Dec 13 at 13:02





              Altought I like this solution and shapeless in general, I don't know how to use this in my case. This is my actual use case: pastebin.com/yCKs0eiQ
              – Gigitsu
              Dec 13 at 13:02












              2














              Scala can't use generic tuple with unknown size because Products don's inherit themeselfs. You can try to use Shapeless or Products from play json lib.






              share|improve this answer
















              • 1




                Can you clarify what "don't inherit themselves" means here? I don't see what that means or how it would help.
                – Travis Brown
                Dec 12 at 10:28










              • Hi :-) The asker didn't specify unknown size but rather any size, which is weaker. For example, shapeless HLists (as you relevantly suggest) are definitely not of unknown size since their size is known at compile time :-) As Travis Brown, I can't quite figure what you mean in this answer, clarifying would be very helpful :-)
                – C4stor
                Dec 12 at 10:49















              2














              Scala can't use generic tuple with unknown size because Products don's inherit themeselfs. You can try to use Shapeless or Products from play json lib.






              share|improve this answer
















              • 1




                Can you clarify what "don't inherit themselves" means here? I don't see what that means or how it would help.
                – Travis Brown
                Dec 12 at 10:28










              • Hi :-) The asker didn't specify unknown size but rather any size, which is weaker. For example, shapeless HLists (as you relevantly suggest) are definitely not of unknown size since their size is known at compile time :-) As Travis Brown, I can't quite figure what you mean in this answer, clarifying would be very helpful :-)
                – C4stor
                Dec 12 at 10:49













              2












              2








              2






              Scala can't use generic tuple with unknown size because Products don's inherit themeselfs. You can try to use Shapeless or Products from play json lib.






              share|improve this answer












              Scala can't use generic tuple with unknown size because Products don's inherit themeselfs. You can try to use Shapeless or Products from play json lib.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Dec 12 at 9:33









              Ivan Aristov

              923




              923







              • 1




                Can you clarify what "don't inherit themselves" means here? I don't see what that means or how it would help.
                – Travis Brown
                Dec 12 at 10:28










              • Hi :-) The asker didn't specify unknown size but rather any size, which is weaker. For example, shapeless HLists (as you relevantly suggest) are definitely not of unknown size since their size is known at compile time :-) As Travis Brown, I can't quite figure what you mean in this answer, clarifying would be very helpful :-)
                – C4stor
                Dec 12 at 10:49












              • 1




                Can you clarify what "don't inherit themselves" means here? I don't see what that means or how it would help.
                – Travis Brown
                Dec 12 at 10:28










              • Hi :-) The asker didn't specify unknown size but rather any size, which is weaker. For example, shapeless HLists (as you relevantly suggest) are definitely not of unknown size since their size is known at compile time :-) As Travis Brown, I can't quite figure what you mean in this answer, clarifying would be very helpful :-)
                – C4stor
                Dec 12 at 10:49







              1




              1




              Can you clarify what "don't inherit themselves" means here? I don't see what that means or how it would help.
              – Travis Brown
              Dec 12 at 10:28




              Can you clarify what "don't inherit themselves" means here? I don't see what that means or how it would help.
              – Travis Brown
              Dec 12 at 10:28












              Hi :-) The asker didn't specify unknown size but rather any size, which is weaker. For example, shapeless HLists (as you relevantly suggest) are definitely not of unknown size since their size is known at compile time :-) As Travis Brown, I can't quite figure what you mean in this answer, clarifying would be very helpful :-)
              – C4stor
              Dec 12 at 10:49




              Hi :-) The asker didn't specify unknown size but rather any size, which is weaker. For example, shapeless HLists (as you relevantly suggest) are definitely not of unknown size since their size is known at compile time :-) As Travis Brown, I can't quite figure what you mean in this answer, clarifying would be very helpful :-)
              – C4stor
              Dec 12 at 10:49











              0














              Because tuples of differing sizes are (almost) unrelated types, if you need the compiler to type-check the calls to getMyClass() then you might have to overload it.



              trait MyTrait 
              def getMyClass(x :(MyClass,_)) :MyClass = x._1
              def getMyClass(x :(MyClass,_,_)) :MyClass = x._1
              def getMyClass(x :(MyClass,_,_,_)) :MyClass = x._1
              def getMyClass(x :(MyClass,_,_,_,_)) :MyClass = x._1






              share|improve this answer

























                0














                Because tuples of differing sizes are (almost) unrelated types, if you need the compiler to type-check the calls to getMyClass() then you might have to overload it.



                trait MyTrait 
                def getMyClass(x :(MyClass,_)) :MyClass = x._1
                def getMyClass(x :(MyClass,_,_)) :MyClass = x._1
                def getMyClass(x :(MyClass,_,_,_)) :MyClass = x._1
                def getMyClass(x :(MyClass,_,_,_,_)) :MyClass = x._1






                share|improve this answer























                  0












                  0








                  0






                  Because tuples of differing sizes are (almost) unrelated types, if you need the compiler to type-check the calls to getMyClass() then you might have to overload it.



                  trait MyTrait 
                  def getMyClass(x :(MyClass,_)) :MyClass = x._1
                  def getMyClass(x :(MyClass,_,_)) :MyClass = x._1
                  def getMyClass(x :(MyClass,_,_,_)) :MyClass = x._1
                  def getMyClass(x :(MyClass,_,_,_,_)) :MyClass = x._1






                  share|improve this answer












                  Because tuples of differing sizes are (almost) unrelated types, if you need the compiler to type-check the calls to getMyClass() then you might have to overload it.



                  trait MyTrait 
                  def getMyClass(x :(MyClass,_)) :MyClass = x._1
                  def getMyClass(x :(MyClass,_,_)) :MyClass = x._1
                  def getMyClass(x :(MyClass,_,_,_)) :MyClass = x._1
                  def getMyClass(x :(MyClass,_,_,_,_)) :MyClass = x._1







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Dec 12 at 9:52









                  jwvh

                  25.3k52038




                  25.3k52038





















                      0














                      You need to inherit your trait from Product, through which you can have productIterator, productArity and, productElement to handle the returned value. Here is an example



                      case class MyClass()

                      trait MyTrait[T <: Product]
                      def getMyClass(x: T): Option[MyClass] =
                      if(
                      x.productIterator.hasNext
                      &&
                      x.productIterator.next().isInstanceOf[MyClass]
                      )
                      Some(x.productIterator.next().asInstanceOf[MyClass])
                      else
                      None



                      case class Test() extends MyTrait[Product]


                      And you can invoke like this



                      Test().getMyClass((MyClass(), 1,3,4,5))
                      //res1: Option[MyClass] = Some(MyClass())

                      Test().getMyClass((1,3,4,5))
                      //res2: Option[MyClass] = None


                      Hope this helps you.






                      share|improve this answer



























                        0














                        You need to inherit your trait from Product, through which you can have productIterator, productArity and, productElement to handle the returned value. Here is an example



                        case class MyClass()

                        trait MyTrait[T <: Product]
                        def getMyClass(x: T): Option[MyClass] =
                        if(
                        x.productIterator.hasNext
                        &&
                        x.productIterator.next().isInstanceOf[MyClass]
                        )
                        Some(x.productIterator.next().asInstanceOf[MyClass])
                        else
                        None



                        case class Test() extends MyTrait[Product]


                        And you can invoke like this



                        Test().getMyClass((MyClass(), 1,3,4,5))
                        //res1: Option[MyClass] = Some(MyClass())

                        Test().getMyClass((1,3,4,5))
                        //res2: Option[MyClass] = None


                        Hope this helps you.






                        share|improve this answer

























                          0












                          0








                          0






                          You need to inherit your trait from Product, through which you can have productIterator, productArity and, productElement to handle the returned value. Here is an example



                          case class MyClass()

                          trait MyTrait[T <: Product]
                          def getMyClass(x: T): Option[MyClass] =
                          if(
                          x.productIterator.hasNext
                          &&
                          x.productIterator.next().isInstanceOf[MyClass]
                          )
                          Some(x.productIterator.next().asInstanceOf[MyClass])
                          else
                          None



                          case class Test() extends MyTrait[Product]


                          And you can invoke like this



                          Test().getMyClass((MyClass(), 1,3,4,5))
                          //res1: Option[MyClass] = Some(MyClass())

                          Test().getMyClass((1,3,4,5))
                          //res2: Option[MyClass] = None


                          Hope this helps you.






                          share|improve this answer














                          You need to inherit your trait from Product, through which you can have productIterator, productArity and, productElement to handle the returned value. Here is an example



                          case class MyClass()

                          trait MyTrait[T <: Product]
                          def getMyClass(x: T): Option[MyClass] =
                          if(
                          x.productIterator.hasNext
                          &&
                          x.productIterator.next().isInstanceOf[MyClass]
                          )
                          Some(x.productIterator.next().asInstanceOf[MyClass])
                          else
                          None



                          case class Test() extends MyTrait[Product]


                          And you can invoke like this



                          Test().getMyClass((MyClass(), 1,3,4,5))
                          //res1: Option[MyClass] = Some(MyClass())

                          Test().getMyClass((1,3,4,5))
                          //res2: Option[MyClass] = None


                          Hope this helps you.







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Dec 12 at 10:00

























                          answered Dec 12 at 9:45









                          Puneeth Reddy V

                          854715




                          854715





















                              -1














                              As others said you can use shapeless:



                              import shapeless.ops.tuple.IsComposite
                              import shapeless.syntax.std.tuple._

                              class MyClass(i : Int)
                              def hello() = println(i)



                              object Tup extends App

                              def getMyClass[P <: Product](p: P)(implicit ev: IsComposite[P]): MyClass =
                              if (p.head.isInstanceOf[MyClass]) p.head.asInstanceOf[MyClass] else throw new Exception()

                              val x= (new MyClass(1),5,6)
                              val y = (new MyClass(2),7)

                              val c = getMyClass(x)
                              val c1 = getMyClass(y)
                              c.hello()
                              c1.hello()

                              val c2 = getMyClass((1,5,6,7)) // exception
                              c2.hello()







                              share|improve this answer




















                              • This doesn't provide any type-safety—the failure happens at runtime, not compile-time. You're not actually doing anything with Shapeless here beyond restricting the tuple to have more than one element, which isn't explicitly a requirement, anyway.
                                – Travis Brown
                                Dec 12 at 11:34










                              • @travis fair enough - though I shapeless is also used to get the first element from the tuple regardless of it and I understood that the question as 1. accept tuples of any size.2 get the MyClass from the first element from the tuple (which by the way your suggested solution does not actually do)
                                – Arnon Rotem-Gal-Oz
                                Dec 12 at 12:34










                              • Why all the casting, then?
                                – Travis Brown
                                Dec 12 at 12:38










                              • @TravisBrown, as I said you're right about that -, could have been done better (e.g. what you did) but it does actually answer the q (how to implement getMyClass(x: T): MyClass = x._1 which works) - your solution is missing a def getMyClass(p: P) : MyClass = p.head to actually answer the question (and be typesafe )
                                – Arnon Rotem-Gal-Oz
                                Dec 12 at 13:19















                              -1














                              As others said you can use shapeless:



                              import shapeless.ops.tuple.IsComposite
                              import shapeless.syntax.std.tuple._

                              class MyClass(i : Int)
                              def hello() = println(i)



                              object Tup extends App

                              def getMyClass[P <: Product](p: P)(implicit ev: IsComposite[P]): MyClass =
                              if (p.head.isInstanceOf[MyClass]) p.head.asInstanceOf[MyClass] else throw new Exception()

                              val x= (new MyClass(1),5,6)
                              val y = (new MyClass(2),7)

                              val c = getMyClass(x)
                              val c1 = getMyClass(y)
                              c.hello()
                              c1.hello()

                              val c2 = getMyClass((1,5,6,7)) // exception
                              c2.hello()







                              share|improve this answer




















                              • This doesn't provide any type-safety—the failure happens at runtime, not compile-time. You're not actually doing anything with Shapeless here beyond restricting the tuple to have more than one element, which isn't explicitly a requirement, anyway.
                                – Travis Brown
                                Dec 12 at 11:34










                              • @travis fair enough - though I shapeless is also used to get the first element from the tuple regardless of it and I understood that the question as 1. accept tuples of any size.2 get the MyClass from the first element from the tuple (which by the way your suggested solution does not actually do)
                                – Arnon Rotem-Gal-Oz
                                Dec 12 at 12:34










                              • Why all the casting, then?
                                – Travis Brown
                                Dec 12 at 12:38










                              • @TravisBrown, as I said you're right about that -, could have been done better (e.g. what you did) but it does actually answer the q (how to implement getMyClass(x: T): MyClass = x._1 which works) - your solution is missing a def getMyClass(p: P) : MyClass = p.head to actually answer the question (and be typesafe )
                                – Arnon Rotem-Gal-Oz
                                Dec 12 at 13:19













                              -1












                              -1








                              -1






                              As others said you can use shapeless:



                              import shapeless.ops.tuple.IsComposite
                              import shapeless.syntax.std.tuple._

                              class MyClass(i : Int)
                              def hello() = println(i)



                              object Tup extends App

                              def getMyClass[P <: Product](p: P)(implicit ev: IsComposite[P]): MyClass =
                              if (p.head.isInstanceOf[MyClass]) p.head.asInstanceOf[MyClass] else throw new Exception()

                              val x= (new MyClass(1),5,6)
                              val y = (new MyClass(2),7)

                              val c = getMyClass(x)
                              val c1 = getMyClass(y)
                              c.hello()
                              c1.hello()

                              val c2 = getMyClass((1,5,6,7)) // exception
                              c2.hello()







                              share|improve this answer












                              As others said you can use shapeless:



                              import shapeless.ops.tuple.IsComposite
                              import shapeless.syntax.std.tuple._

                              class MyClass(i : Int)
                              def hello() = println(i)



                              object Tup extends App

                              def getMyClass[P <: Product](p: P)(implicit ev: IsComposite[P]): MyClass =
                              if (p.head.isInstanceOf[MyClass]) p.head.asInstanceOf[MyClass] else throw new Exception()

                              val x= (new MyClass(1),5,6)
                              val y = (new MyClass(2),7)

                              val c = getMyClass(x)
                              val c1 = getMyClass(y)
                              c.hello()
                              c1.hello()

                              val c2 = getMyClass((1,5,6,7)) // exception
                              c2.hello()








                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Dec 12 at 10:53









                              Arnon Rotem-Gal-Oz

                              18.9k13360




                              18.9k13360











                              • This doesn't provide any type-safety—the failure happens at runtime, not compile-time. You're not actually doing anything with Shapeless here beyond restricting the tuple to have more than one element, which isn't explicitly a requirement, anyway.
                                – Travis Brown
                                Dec 12 at 11:34










                              • @travis fair enough - though I shapeless is also used to get the first element from the tuple regardless of it and I understood that the question as 1. accept tuples of any size.2 get the MyClass from the first element from the tuple (which by the way your suggested solution does not actually do)
                                – Arnon Rotem-Gal-Oz
                                Dec 12 at 12:34










                              • Why all the casting, then?
                                – Travis Brown
                                Dec 12 at 12:38










                              • @TravisBrown, as I said you're right about that -, could have been done better (e.g. what you did) but it does actually answer the q (how to implement getMyClass(x: T): MyClass = x._1 which works) - your solution is missing a def getMyClass(p: P) : MyClass = p.head to actually answer the question (and be typesafe )
                                – Arnon Rotem-Gal-Oz
                                Dec 12 at 13:19
















                              • This doesn't provide any type-safety—the failure happens at runtime, not compile-time. You're not actually doing anything with Shapeless here beyond restricting the tuple to have more than one element, which isn't explicitly a requirement, anyway.
                                – Travis Brown
                                Dec 12 at 11:34










                              • @travis fair enough - though I shapeless is also used to get the first element from the tuple regardless of it and I understood that the question as 1. accept tuples of any size.2 get the MyClass from the first element from the tuple (which by the way your suggested solution does not actually do)
                                – Arnon Rotem-Gal-Oz
                                Dec 12 at 12:34










                              • Why all the casting, then?
                                – Travis Brown
                                Dec 12 at 12:38










                              • @TravisBrown, as I said you're right about that -, could have been done better (e.g. what you did) but it does actually answer the q (how to implement getMyClass(x: T): MyClass = x._1 which works) - your solution is missing a def getMyClass(p: P) : MyClass = p.head to actually answer the question (and be typesafe )
                                – Arnon Rotem-Gal-Oz
                                Dec 12 at 13:19















                              This doesn't provide any type-safety—the failure happens at runtime, not compile-time. You're not actually doing anything with Shapeless here beyond restricting the tuple to have more than one element, which isn't explicitly a requirement, anyway.
                              – Travis Brown
                              Dec 12 at 11:34




                              This doesn't provide any type-safety—the failure happens at runtime, not compile-time. You're not actually doing anything with Shapeless here beyond restricting the tuple to have more than one element, which isn't explicitly a requirement, anyway.
                              – Travis Brown
                              Dec 12 at 11:34












                              @travis fair enough - though I shapeless is also used to get the first element from the tuple regardless of it and I understood that the question as 1. accept tuples of any size.2 get the MyClass from the first element from the tuple (which by the way your suggested solution does not actually do)
                              – Arnon Rotem-Gal-Oz
                              Dec 12 at 12:34




                              @travis fair enough - though I shapeless is also used to get the first element from the tuple regardless of it and I understood that the question as 1. accept tuples of any size.2 get the MyClass from the first element from the tuple (which by the way your suggested solution does not actually do)
                              – Arnon Rotem-Gal-Oz
                              Dec 12 at 12:34












                              Why all the casting, then?
                              – Travis Brown
                              Dec 12 at 12:38




                              Why all the casting, then?
                              – Travis Brown
                              Dec 12 at 12:38












                              @TravisBrown, as I said you're right about that -, could have been done better (e.g. what you did) but it does actually answer the q (how to implement getMyClass(x: T): MyClass = x._1 which works) - your solution is missing a def getMyClass(p: P) : MyClass = p.head to actually answer the question (and be typesafe )
                              – Arnon Rotem-Gal-Oz
                              Dec 12 at 13:19




                              @TravisBrown, as I said you're right about that -, could have been done better (e.g. what you did) but it does actually answer the q (how to implement getMyClass(x: T): MyClass = x._1 which works) - your solution is missing a def getMyClass(p: P) : MyClass = p.head to actually answer the question (and be typesafe )
                              – Arnon Rotem-Gal-Oz
                              Dec 12 at 13:19











                              -1














                              If you are looking for compile time guarantee then this is one of the use cases for
                              Shapeless,



                              You need to add Shapeless in your build.sbt,



                              libraryDependencies ++= Seq("
                              com.chuusai" %% "shapeless" % "2.3.3"
                              )


                              Now, you can use Shapeless to define a typesafe getter which comes with compile time guarantees,



                              scala> import shapeless._
                              // import shapeless._

                              scala> import ops.tuple.IsComposite
                              // import ops.tuple.IsComposite

                              scala> import syntax.std.tuple._
                              // import syntax.std.tuple._

                              scala> case class Omg(omg: String)
                              // defined class Omg

                              scala> val myStringTuple = ("All is well", 42, "hope")
                              // myStringTuple: (String, Int, String) = (All is well,42,hope)

                              scala> val myOmgTuple = (Omg("All is well"), 42, "hope")
                              // myOmgTuple: (Omg, Int, String) = (Omg(All is well),42,hope)


                              Now if you want to enrich your tuples with a "first" getter with a specific type then,



                              scala> implicit class GetterForProduct[B <: Product](b: B) 

                              // defined class GetterForProduct

                              scala> val myString = myStringTuple.getFirst[String]
                              // myString: String = All is well

                              scala> val myOmgError = myOmgTuple.getFirst[String]
                              // <console>:24: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
                              // val myOmgError = myOmgTuple.getFirst[String]
                              // ^

                              scala> val myOmg = myOmgTuple.getFirst[Omg]
                              // myOmg: Omg = Omg(All is well


                              If you don't need the implicit enrichment and are just looking for a way to "lock" the type in a getter and use it for corresponding types,



                              scala> trait FirstGetterInProduct[A] 

                              // defined trait FirstGetterInProduct

                              scala> object firstGetterInProductForString extends FirstGetterInProduct[String]
                              // defined object firstGetterInProductForString

                              scala> object firstGetterInProductForOmg extends FirstGetterInProduct[Omg]
                              // defined object firstGetterInProductForOmg

                              // Right tuple with right getter,
                              scala> val myString = firstGetterInProductForString.getFirst(myStringTuple)
                              // myString: String = All is well

                              // will fail at compile time for tuple with different type for first
                              scala> val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
                              // <console>:23: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
                              // val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
                              // ^

                              scala> val myOmg = firstGetterInProductForOmg.getFirst(myOmgTuple)
                              // myOmg: Omg = Omg(All is well)





                              share|improve this answer






















                              • What is the "compile time guarantee" here? The OP has requested that tuples of any length, but only with the 1st element of a specific type, be accepted. (Not my down-vote.)
                                – jwvh
                                Dec 12 at 11:52










                              • @jwvh You are right. Fixed.
                                – Sarvesh Kumar Singh
                                Dec 12 at 14:08















                              -1














                              If you are looking for compile time guarantee then this is one of the use cases for
                              Shapeless,



                              You need to add Shapeless in your build.sbt,



                              libraryDependencies ++= Seq("
                              com.chuusai" %% "shapeless" % "2.3.3"
                              )


                              Now, you can use Shapeless to define a typesafe getter which comes with compile time guarantees,



                              scala> import shapeless._
                              // import shapeless._

                              scala> import ops.tuple.IsComposite
                              // import ops.tuple.IsComposite

                              scala> import syntax.std.tuple._
                              // import syntax.std.tuple._

                              scala> case class Omg(omg: String)
                              // defined class Omg

                              scala> val myStringTuple = ("All is well", 42, "hope")
                              // myStringTuple: (String, Int, String) = (All is well,42,hope)

                              scala> val myOmgTuple = (Omg("All is well"), 42, "hope")
                              // myOmgTuple: (Omg, Int, String) = (Omg(All is well),42,hope)


                              Now if you want to enrich your tuples with a "first" getter with a specific type then,



                              scala> implicit class GetterForProduct[B <: Product](b: B) 

                              // defined class GetterForProduct

                              scala> val myString = myStringTuple.getFirst[String]
                              // myString: String = All is well

                              scala> val myOmgError = myOmgTuple.getFirst[String]
                              // <console>:24: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
                              // val myOmgError = myOmgTuple.getFirst[String]
                              // ^

                              scala> val myOmg = myOmgTuple.getFirst[Omg]
                              // myOmg: Omg = Omg(All is well


                              If you don't need the implicit enrichment and are just looking for a way to "lock" the type in a getter and use it for corresponding types,



                              scala> trait FirstGetterInProduct[A] 

                              // defined trait FirstGetterInProduct

                              scala> object firstGetterInProductForString extends FirstGetterInProduct[String]
                              // defined object firstGetterInProductForString

                              scala> object firstGetterInProductForOmg extends FirstGetterInProduct[Omg]
                              // defined object firstGetterInProductForOmg

                              // Right tuple with right getter,
                              scala> val myString = firstGetterInProductForString.getFirst(myStringTuple)
                              // myString: String = All is well

                              // will fail at compile time for tuple with different type for first
                              scala> val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
                              // <console>:23: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
                              // val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
                              // ^

                              scala> val myOmg = firstGetterInProductForOmg.getFirst(myOmgTuple)
                              // myOmg: Omg = Omg(All is well)





                              share|improve this answer






















                              • What is the "compile time guarantee" here? The OP has requested that tuples of any length, but only with the 1st element of a specific type, be accepted. (Not my down-vote.)
                                – jwvh
                                Dec 12 at 11:52










                              • @jwvh You are right. Fixed.
                                – Sarvesh Kumar Singh
                                Dec 12 at 14:08













                              -1












                              -1








                              -1






                              If you are looking for compile time guarantee then this is one of the use cases for
                              Shapeless,



                              You need to add Shapeless in your build.sbt,



                              libraryDependencies ++= Seq("
                              com.chuusai" %% "shapeless" % "2.3.3"
                              )


                              Now, you can use Shapeless to define a typesafe getter which comes with compile time guarantees,



                              scala> import shapeless._
                              // import shapeless._

                              scala> import ops.tuple.IsComposite
                              // import ops.tuple.IsComposite

                              scala> import syntax.std.tuple._
                              // import syntax.std.tuple._

                              scala> case class Omg(omg: String)
                              // defined class Omg

                              scala> val myStringTuple = ("All is well", 42, "hope")
                              // myStringTuple: (String, Int, String) = (All is well,42,hope)

                              scala> val myOmgTuple = (Omg("All is well"), 42, "hope")
                              // myOmgTuple: (Omg, Int, String) = (Omg(All is well),42,hope)


                              Now if you want to enrich your tuples with a "first" getter with a specific type then,



                              scala> implicit class GetterForProduct[B <: Product](b: B) 

                              // defined class GetterForProduct

                              scala> val myString = myStringTuple.getFirst[String]
                              // myString: String = All is well

                              scala> val myOmgError = myOmgTuple.getFirst[String]
                              // <console>:24: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
                              // val myOmgError = myOmgTuple.getFirst[String]
                              // ^

                              scala> val myOmg = myOmgTuple.getFirst[Omg]
                              // myOmg: Omg = Omg(All is well


                              If you don't need the implicit enrichment and are just looking for a way to "lock" the type in a getter and use it for corresponding types,



                              scala> trait FirstGetterInProduct[A] 

                              // defined trait FirstGetterInProduct

                              scala> object firstGetterInProductForString extends FirstGetterInProduct[String]
                              // defined object firstGetterInProductForString

                              scala> object firstGetterInProductForOmg extends FirstGetterInProduct[Omg]
                              // defined object firstGetterInProductForOmg

                              // Right tuple with right getter,
                              scala> val myString = firstGetterInProductForString.getFirst(myStringTuple)
                              // myString: String = All is well

                              // will fail at compile time for tuple with different type for first
                              scala> val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
                              // <console>:23: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
                              // val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
                              // ^

                              scala> val myOmg = firstGetterInProductForOmg.getFirst(myOmgTuple)
                              // myOmg: Omg = Omg(All is well)





                              share|improve this answer














                              If you are looking for compile time guarantee then this is one of the use cases for
                              Shapeless,



                              You need to add Shapeless in your build.sbt,



                              libraryDependencies ++= Seq("
                              com.chuusai" %% "shapeless" % "2.3.3"
                              )


                              Now, you can use Shapeless to define a typesafe getter which comes with compile time guarantees,



                              scala> import shapeless._
                              // import shapeless._

                              scala> import ops.tuple.IsComposite
                              // import ops.tuple.IsComposite

                              scala> import syntax.std.tuple._
                              // import syntax.std.tuple._

                              scala> case class Omg(omg: String)
                              // defined class Omg

                              scala> val myStringTuple = ("All is well", 42, "hope")
                              // myStringTuple: (String, Int, String) = (All is well,42,hope)

                              scala> val myOmgTuple = (Omg("All is well"), 42, "hope")
                              // myOmgTuple: (Omg, Int, String) = (Omg(All is well),42,hope)


                              Now if you want to enrich your tuples with a "first" getter with a specific type then,



                              scala> implicit class GetterForProduct[B <: Product](b: B) 

                              // defined class GetterForProduct

                              scala> val myString = myStringTuple.getFirst[String]
                              // myString: String = All is well

                              scala> val myOmgError = myOmgTuple.getFirst[String]
                              // <console>:24: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
                              // val myOmgError = myOmgTuple.getFirst[String]
                              // ^

                              scala> val myOmg = myOmgTuple.getFirst[Omg]
                              // myOmg: Omg = Omg(All is well


                              If you don't need the implicit enrichment and are just looking for a way to "lock" the type in a getter and use it for corresponding types,



                              scala> trait FirstGetterInProduct[A] 

                              // defined trait FirstGetterInProduct

                              scala> object firstGetterInProductForString extends FirstGetterInProduct[String]
                              // defined object firstGetterInProductForString

                              scala> object firstGetterInProductForOmg extends FirstGetterInProduct[Omg]
                              // defined object firstGetterInProductForOmg

                              // Right tuple with right getter,
                              scala> val myString = firstGetterInProductForString.getFirst(myStringTuple)
                              // myString: String = All is well

                              // will fail at compile time for tuple with different type for first
                              scala> val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
                              // <console>:23: error: could not find implicit value for parameter comp: shapeless.ops.tuple.IsComposite[(Omg, Int, String)]type H = String
                              // val myOmgError = firstGetterInProductForString.getFirst(myOmgTuple)
                              // ^

                              scala> val myOmg = firstGetterInProductForOmg.getFirst(myOmgTuple)
                              // myOmg: Omg = Omg(All is well)






                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Dec 12 at 14:08

























                              answered Dec 12 at 11:32









                              Sarvesh Kumar Singh

                              8,0901634




                              8,0901634











                              • What is the "compile time guarantee" here? The OP has requested that tuples of any length, but only with the 1st element of a specific type, be accepted. (Not my down-vote.)
                                – jwvh
                                Dec 12 at 11:52










                              • @jwvh You are right. Fixed.
                                – Sarvesh Kumar Singh
                                Dec 12 at 14:08
















                              • What is the "compile time guarantee" here? The OP has requested that tuples of any length, but only with the 1st element of a specific type, be accepted. (Not my down-vote.)
                                – jwvh
                                Dec 12 at 11:52










                              • @jwvh You are right. Fixed.
                                – Sarvesh Kumar Singh
                                Dec 12 at 14:08















                              What is the "compile time guarantee" here? The OP has requested that tuples of any length, but only with the 1st element of a specific type, be accepted. (Not my down-vote.)
                              – jwvh
                              Dec 12 at 11:52




                              What is the "compile time guarantee" here? The OP has requested that tuples of any length, but only with the 1st element of a specific type, be accepted. (Not my down-vote.)
                              – jwvh
                              Dec 12 at 11:52












                              @jwvh You are right. Fixed.
                              – Sarvesh Kumar Singh
                              Dec 12 at 14:08




                              @jwvh You are right. Fixed.
                              – Sarvesh Kumar Singh
                              Dec 12 at 14:08

















                              draft saved

                              draft discarded
















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53739656%2fscala-generic-tuple%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown






                              Popular posts from this blog

                              How to check contact read email or not when send email to Individual?

                              Displaying single band from multi-band raster using QGIS

                              How many registers does an x86_64 CPU actually have?