Trying to understand ClassTag and TypeTag in ScalaWhat is a “context bound” in Scala?Read entire file in Scala?Scala vs. Groovy vs. ClojureIs the Scala 2.8 collections library a case of “the longest suicide note in history”?Difference between object and class in ScalaWhat are all the uses of an underscore in Scala?Understanding implicit in ScalaScala: What is a TypeTag and how do I use it?How save a TypeTag and then use it later to reattach the type to an Any (Scala 2.10)How to map HList to List[Type], List[TypeTag], or List[String]Scala ambiguity with paren-less function calls
Does WiFi affect the quality of images downloaded from the internet?
The best in flight meal option for those suffering from reflux
Are skill challenges an official option or homebrewed?
Did I need a visa in 2004 and 2006?
Is Jesus the last Prophet?
Is all-caps blackletter no longer taboo?
Am I being scammed by a sugar daddy?
What did the 8086 (and 8088) do upon encountering an illegal instruction?
What is the theme of analysis?
Must I use my personal social media account for work?
Is there a frequency comparator device?
How can calculate the turn-off time of an LDO?
What class is best to play when a level behind the rest of the party?
Dedicated bike GPS computer over smartphone
Is there a radar system monitoring the UK mainland border?
Why is my Taiyaki (Cake that looks like a fish) too hard and dry?
Why would a home insurer offer a discount based on credit score?
How can powerful telekinesis avoid violating Newton's 3rd Law?
Can I use 220 V outlets on a 15 ampere breaker and wire it up as 110 V?
Can I get a photo of an Ancient Arrow?
Is it true that "only photographers care about noise"?
Changing the PK column of a data extension without completely recreating it
Undocumented incompatibility between changes and siunitx?
What do you call the action of "describing events as they happen" like sports anchors do?
Trying to understand ClassTag and TypeTag in Scala
What is a “context bound” in Scala?Read entire file in Scala?Scala vs. Groovy vs. ClojureIs the Scala 2.8 collections library a case of “the longest suicide note in history”?Difference between object and class in ScalaWhat are all the uses of an underscore in Scala?Understanding implicit in ScalaScala: What is a TypeTag and how do I use it?How save a TypeTag and then use it later to reattach the type to an Any (Scala 2.10)How to map HList to List[Type], List[TypeTag], or List[String]Scala ambiguity with paren-less function calls
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I am trying to understand how we can overcome type erasure in scala using ClassTag
and TypeTag
. I wrote the following examples which are generic functions that try to filter out List[TNode]
where TNode
is equal to TMatch
. However, I expect in recognizeUsingTypeTag
, the function shall not call extractUsingClassTag
is the generic type of list is equal to TMatch
(or the message gets printed), but my assumption is apparently wrong. Thank you.
object Extractor
import scala.reflect.ClassTag
def extractFail[TNode, TMatch](list: List[TNode]) = list.filter
case _: TMatch => true
case _ => false
.map(x => x.asInstanceOf[TMatch])
def extractUsingClassTag[TNode, TMatch](list: List[TNode])(implicit tag1: ClassTag[TNode], tag2: ClassTag[TMatch]) = list.filter
case _: TMatch => true
case _ => false
.map(x => x.asInstanceOf[TMatch])
import scala.reflect.runtime.universe._
def recognizeUsingTypeTag[TNode, TMatch](list: List[TNode])(implicit tag1: TypeTag[TNode], tag2: TypeTag[TMatch], tag3: ClassTag[TNode], tag4: ClassTag[TMatch]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
val homogeneous: List[String] = List("Hello", "World!")
val heterogeneous: List[Any] = List("Hello", "World!", 123, false)
println("extractFail")
println(Extractor.extractFail[Any, String](homogeneous))
println(Extractor.extractFail[Any, String](heterogeneous) + "n")
println("extractUsingClassTag")
println(Extractor.extractUsingClassTag[Any, String](homogeneous))
println(Extractor.extractUsingClassTag[Any, String](heterogeneous) + "n")
println("recognizeUsingTypeTag")
println(Extractor.recognizeUsingTypeTag[Any, String](homogeneous))
println(Extractor.recognizeUsingTypeTag[Any, String](heterogeneous) + "n")
Console:
extractFail
List(Hello, World!)
List(Hello, World!, 123, false)
extractUsingClassTag
List(Hello, World!)
List(Hello, World!)
recognizeUsingTypeTag
List(Hello, World!)
List(Hello, World!)
scala
add a comment |
I am trying to understand how we can overcome type erasure in scala using ClassTag
and TypeTag
. I wrote the following examples which are generic functions that try to filter out List[TNode]
where TNode
is equal to TMatch
. However, I expect in recognizeUsingTypeTag
, the function shall not call extractUsingClassTag
is the generic type of list is equal to TMatch
(or the message gets printed), but my assumption is apparently wrong. Thank you.
object Extractor
import scala.reflect.ClassTag
def extractFail[TNode, TMatch](list: List[TNode]) = list.filter
case _: TMatch => true
case _ => false
.map(x => x.asInstanceOf[TMatch])
def extractUsingClassTag[TNode, TMatch](list: List[TNode])(implicit tag1: ClassTag[TNode], tag2: ClassTag[TMatch]) = list.filter
case _: TMatch => true
case _ => false
.map(x => x.asInstanceOf[TMatch])
import scala.reflect.runtime.universe._
def recognizeUsingTypeTag[TNode, TMatch](list: List[TNode])(implicit tag1: TypeTag[TNode], tag2: TypeTag[TMatch], tag3: ClassTag[TNode], tag4: ClassTag[TMatch]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
val homogeneous: List[String] = List("Hello", "World!")
val heterogeneous: List[Any] = List("Hello", "World!", 123, false)
println("extractFail")
println(Extractor.extractFail[Any, String](homogeneous))
println(Extractor.extractFail[Any, String](heterogeneous) + "n")
println("extractUsingClassTag")
println(Extractor.extractUsingClassTag[Any, String](homogeneous))
println(Extractor.extractUsingClassTag[Any, String](heterogeneous) + "n")
println("recognizeUsingTypeTag")
println(Extractor.recognizeUsingTypeTag[Any, String](homogeneous))
println(Extractor.recognizeUsingTypeTag[Any, String](heterogeneous) + "n")
Console:
extractFail
List(Hello, World!)
List(Hello, World!, 123, false)
extractUsingClassTag
List(Hello, World!)
List(Hello, World!)
recognizeUsingTypeTag
List(Hello, World!)
List(Hello, World!)
scala
add a comment |
I am trying to understand how we can overcome type erasure in scala using ClassTag
and TypeTag
. I wrote the following examples which are generic functions that try to filter out List[TNode]
where TNode
is equal to TMatch
. However, I expect in recognizeUsingTypeTag
, the function shall not call extractUsingClassTag
is the generic type of list is equal to TMatch
(or the message gets printed), but my assumption is apparently wrong. Thank you.
object Extractor
import scala.reflect.ClassTag
def extractFail[TNode, TMatch](list: List[TNode]) = list.filter
case _: TMatch => true
case _ => false
.map(x => x.asInstanceOf[TMatch])
def extractUsingClassTag[TNode, TMatch](list: List[TNode])(implicit tag1: ClassTag[TNode], tag2: ClassTag[TMatch]) = list.filter
case _: TMatch => true
case _ => false
.map(x => x.asInstanceOf[TMatch])
import scala.reflect.runtime.universe._
def recognizeUsingTypeTag[TNode, TMatch](list: List[TNode])(implicit tag1: TypeTag[TNode], tag2: TypeTag[TMatch], tag3: ClassTag[TNode], tag4: ClassTag[TMatch]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
val homogeneous: List[String] = List("Hello", "World!")
val heterogeneous: List[Any] = List("Hello", "World!", 123, false)
println("extractFail")
println(Extractor.extractFail[Any, String](homogeneous))
println(Extractor.extractFail[Any, String](heterogeneous) + "n")
println("extractUsingClassTag")
println(Extractor.extractUsingClassTag[Any, String](homogeneous))
println(Extractor.extractUsingClassTag[Any, String](heterogeneous) + "n")
println("recognizeUsingTypeTag")
println(Extractor.recognizeUsingTypeTag[Any, String](homogeneous))
println(Extractor.recognizeUsingTypeTag[Any, String](heterogeneous) + "n")
Console:
extractFail
List(Hello, World!)
List(Hello, World!, 123, false)
extractUsingClassTag
List(Hello, World!)
List(Hello, World!)
recognizeUsingTypeTag
List(Hello, World!)
List(Hello, World!)
scala
I am trying to understand how we can overcome type erasure in scala using ClassTag
and TypeTag
. I wrote the following examples which are generic functions that try to filter out List[TNode]
where TNode
is equal to TMatch
. However, I expect in recognizeUsingTypeTag
, the function shall not call extractUsingClassTag
is the generic type of list is equal to TMatch
(or the message gets printed), but my assumption is apparently wrong. Thank you.
object Extractor
import scala.reflect.ClassTag
def extractFail[TNode, TMatch](list: List[TNode]) = list.filter
case _: TMatch => true
case _ => false
.map(x => x.asInstanceOf[TMatch])
def extractUsingClassTag[TNode, TMatch](list: List[TNode])(implicit tag1: ClassTag[TNode], tag2: ClassTag[TMatch]) = list.filter
case _: TMatch => true
case _ => false
.map(x => x.asInstanceOf[TMatch])
import scala.reflect.runtime.universe._
def recognizeUsingTypeTag[TNode, TMatch](list: List[TNode])(implicit tag1: TypeTag[TNode], tag2: TypeTag[TMatch], tag3: ClassTag[TNode], tag4: ClassTag[TMatch]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
val homogeneous: List[String] = List("Hello", "World!")
val heterogeneous: List[Any] = List("Hello", "World!", 123, false)
println("extractFail")
println(Extractor.extractFail[Any, String](homogeneous))
println(Extractor.extractFail[Any, String](heterogeneous) + "n")
println("extractUsingClassTag")
println(Extractor.extractUsingClassTag[Any, String](homogeneous))
println(Extractor.extractUsingClassTag[Any, String](heterogeneous) + "n")
println("recognizeUsingTypeTag")
println(Extractor.recognizeUsingTypeTag[Any, String](homogeneous))
println(Extractor.recognizeUsingTypeTag[Any, String](heterogeneous) + "n")
Console:
extractFail
List(Hello, World!)
List(Hello, World!, 123, false)
extractUsingClassTag
List(Hello, World!)
List(Hello, World!)
recognizeUsingTypeTag
List(Hello, World!)
List(Hello, World!)
scala
scala
asked Mar 25 at 0:10
Node.JSNode.JS
97611041
97611041
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Why this does not get printed for List[String]
Because you specified explicit type parameters: [Any, String]
, so case _ if typeOf[TNode] =:= typeOf[TMatch]
compares typeOf[Any] =:= typeOf[String]
.
Since you do need to specify String
for TMatch
, but want TNode
to be inferred, the usual way to do it is splitting type parameters into two lists by creating an intermediate class:
// in Extractor
class RecognizeUsingTypeTag[TMatch : TypeTag : ClassTag]
def apply[TNode : TypeTag : ClassTag](list: List[TNode]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
def recognizeUsingTypeTag[TMatch : TypeTag : ClassTag] = new RecognizeUsingTypeTag[TMatch]
println(Extractor.recognizeUsingTypeTag[String].apply(homogeneous)) // inferred as apply[String]
println(Extractor.recognizeUsingTypeTag[String].apply(heterogeneous) + "n") // inferred as apply[Any]
When you have implicit parameters like that and don't need their names, it's preferred to use context bounds: T : TypeTag : ClassTag
adds two implicit parameters of types TypeTag[T]
and ClassTag[T]
.
I am getting a compile error. I think those implicit parameters for theapply
methods need to be specified beside the method generic types, not beside theList[TNode]
– Node.JS
Mar 25 at 13:12
1
@Node.JS Yes, fixed.
– Alexey Romanov
Mar 25 at 13:28
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55329802%2ftrying-to-understand-classtag-and-typetag-in-scala%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Why this does not get printed for List[String]
Because you specified explicit type parameters: [Any, String]
, so case _ if typeOf[TNode] =:= typeOf[TMatch]
compares typeOf[Any] =:= typeOf[String]
.
Since you do need to specify String
for TMatch
, but want TNode
to be inferred, the usual way to do it is splitting type parameters into two lists by creating an intermediate class:
// in Extractor
class RecognizeUsingTypeTag[TMatch : TypeTag : ClassTag]
def apply[TNode : TypeTag : ClassTag](list: List[TNode]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
def recognizeUsingTypeTag[TMatch : TypeTag : ClassTag] = new RecognizeUsingTypeTag[TMatch]
println(Extractor.recognizeUsingTypeTag[String].apply(homogeneous)) // inferred as apply[String]
println(Extractor.recognizeUsingTypeTag[String].apply(heterogeneous) + "n") // inferred as apply[Any]
When you have implicit parameters like that and don't need their names, it's preferred to use context bounds: T : TypeTag : ClassTag
adds two implicit parameters of types TypeTag[T]
and ClassTag[T]
.
I am getting a compile error. I think those implicit parameters for theapply
methods need to be specified beside the method generic types, not beside theList[TNode]
– Node.JS
Mar 25 at 13:12
1
@Node.JS Yes, fixed.
– Alexey Romanov
Mar 25 at 13:28
add a comment |
Why this does not get printed for List[String]
Because you specified explicit type parameters: [Any, String]
, so case _ if typeOf[TNode] =:= typeOf[TMatch]
compares typeOf[Any] =:= typeOf[String]
.
Since you do need to specify String
for TMatch
, but want TNode
to be inferred, the usual way to do it is splitting type parameters into two lists by creating an intermediate class:
// in Extractor
class RecognizeUsingTypeTag[TMatch : TypeTag : ClassTag]
def apply[TNode : TypeTag : ClassTag](list: List[TNode]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
def recognizeUsingTypeTag[TMatch : TypeTag : ClassTag] = new RecognizeUsingTypeTag[TMatch]
println(Extractor.recognizeUsingTypeTag[String].apply(homogeneous)) // inferred as apply[String]
println(Extractor.recognizeUsingTypeTag[String].apply(heterogeneous) + "n") // inferred as apply[Any]
When you have implicit parameters like that and don't need their names, it's preferred to use context bounds: T : TypeTag : ClassTag
adds two implicit parameters of types TypeTag[T]
and ClassTag[T]
.
I am getting a compile error. I think those implicit parameters for theapply
methods need to be specified beside the method generic types, not beside theList[TNode]
– Node.JS
Mar 25 at 13:12
1
@Node.JS Yes, fixed.
– Alexey Romanov
Mar 25 at 13:28
add a comment |
Why this does not get printed for List[String]
Because you specified explicit type parameters: [Any, String]
, so case _ if typeOf[TNode] =:= typeOf[TMatch]
compares typeOf[Any] =:= typeOf[String]
.
Since you do need to specify String
for TMatch
, but want TNode
to be inferred, the usual way to do it is splitting type parameters into two lists by creating an intermediate class:
// in Extractor
class RecognizeUsingTypeTag[TMatch : TypeTag : ClassTag]
def apply[TNode : TypeTag : ClassTag](list: List[TNode]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
def recognizeUsingTypeTag[TMatch : TypeTag : ClassTag] = new RecognizeUsingTypeTag[TMatch]
println(Extractor.recognizeUsingTypeTag[String].apply(homogeneous)) // inferred as apply[String]
println(Extractor.recognizeUsingTypeTag[String].apply(heterogeneous) + "n") // inferred as apply[Any]
When you have implicit parameters like that and don't need their names, it's preferred to use context bounds: T : TypeTag : ClassTag
adds two implicit parameters of types TypeTag[T]
and ClassTag[T]
.
Why this does not get printed for List[String]
Because you specified explicit type parameters: [Any, String]
, so case _ if typeOf[TNode] =:= typeOf[TMatch]
compares typeOf[Any] =:= typeOf[String]
.
Since you do need to specify String
for TMatch
, but want TNode
to be inferred, the usual way to do it is splitting type parameters into two lists by creating an intermediate class:
// in Extractor
class RecognizeUsingTypeTag[TMatch : TypeTag : ClassTag]
def apply[TNode : TypeTag : ClassTag](list: List[TNode]) = list match
case _ if typeOf[TNode] =:= typeOf[TMatch] =>
//
// Why this does not get printed for List[String]
//
println("This should get printed when called for homogeneous")
list.asInstanceOf[List[TMatch]]
case _ => extractUsingClassTag[TNode, TMatch](list)
def recognizeUsingTypeTag[TMatch : TypeTag : ClassTag] = new RecognizeUsingTypeTag[TMatch]
println(Extractor.recognizeUsingTypeTag[String].apply(homogeneous)) // inferred as apply[String]
println(Extractor.recognizeUsingTypeTag[String].apply(heterogeneous) + "n") // inferred as apply[Any]
When you have implicit parameters like that and don't need their names, it's preferred to use context bounds: T : TypeTag : ClassTag
adds two implicit parameters of types TypeTag[T]
and ClassTag[T]
.
edited Mar 25 at 13:28
answered Mar 25 at 7:16
Alexey RomanovAlexey Romanov
114k26218364
114k26218364
I am getting a compile error. I think those implicit parameters for theapply
methods need to be specified beside the method generic types, not beside theList[TNode]
– Node.JS
Mar 25 at 13:12
1
@Node.JS Yes, fixed.
– Alexey Romanov
Mar 25 at 13:28
add a comment |
I am getting a compile error. I think those implicit parameters for theapply
methods need to be specified beside the method generic types, not beside theList[TNode]
– Node.JS
Mar 25 at 13:12
1
@Node.JS Yes, fixed.
– Alexey Romanov
Mar 25 at 13:28
I am getting a compile error. I think those implicit parameters for the
apply
methods need to be specified beside the method generic types, not beside the List[TNode]
– Node.JS
Mar 25 at 13:12
I am getting a compile error. I think those implicit parameters for the
apply
methods need to be specified beside the method generic types, not beside the List[TNode]
– Node.JS
Mar 25 at 13:12
1
1
@Node.JS Yes, fixed.
– Alexey Romanov
Mar 25 at 13:28
@Node.JS Yes, fixed.
– Alexey Romanov
Mar 25 at 13:28
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55329802%2ftrying-to-understand-classtag-and-typetag-in-scala%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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