0
object Main extends App {
  def foo[A](somelist: List[A])(implicit m: Manifest[A]): String = somelist match {
    case _ : List[Int] => "we have a list of int!"
    case _ => "have no idea what this list is"
  }
}
Main.foo(List[String]("somestring"))

results in:

res0: String = we have a list of int!

I was sure the whole purpose of Manifest was to pass information to the JVM why doesnt this work? (PS I'm aware TypeTag is the updated way to do it I want to try it with Manifest).

thanks

Jas
  • 14,493
  • 27
  • 97
  • 148
  • Don't you get a compiler warning about erasure on line `case _: List[Int] =>`? – cchantep Feb 26 '16 at 08:34
  • I do get `Warning:(5, 14) non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure case _ : List[Int] => "we have a list of int!" ^` wasn't the Manifest supposed to fix that? – Jas Feb 26 '16 at 08:37
  • No it cannot be fixed in this way. Type pattern in general should be avoided. You can try `case (_: Int) :: _ => ???` – cchantep Feb 26 '16 at 08:40
  • i'm doing this to practice `Manifest` and to understand what it is not for real world programming. I get it if i want to access the type which I pass in `List[A]` then I need to check it in `m` and not in `somelist` – Jas Feb 26 '16 at 08:41
  • but `case (_: Int) ` checks if the `somelist` is `Int` its never `Int` its always a list of something isn't it? – Jas Feb 26 '16 at 08:44
  • It checks whether the list start with an `Int`, assuming the element type is coherent (not a naughty `List[Any]`) – cchantep Feb 26 '16 at 09:06

2 Answers2

1

The only use of Manifest[A] in pattern-matching is to allow you to match against A:

somelist match {
  case _: A => ...
  case _ => ...
}

not against any type you want to.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • in this post http://stackoverflow.com/questions/3213510/what-is-a-manifest-in-scala-and-when-do-you-need-it he is checking if `manifest` is of type `manifest[String]` why couldn't i also compare to `Manifest[String]`? isn't the whole purpose of `Manifest` to store the type to have it available in runtime? – Jas Feb 26 '16 at 08:50
  • in the post he is doing: `(implicit m: Manifest[T]) = { if (m <:< manifest[String])` – Jas Feb 26 '16 at 08:59
  • You can. Matching against `_: List[Int]` doesn't do this for you (it would actually be incorrect if it did: consider `foo(List[String]())`). – Alexey Romanov Feb 26 '16 at 09:02
1

as it turns out there is a Predef manifest definition so you should compare the m only to this predef manifest in the following way

object Main extends App {
  println(Main.foo(List[String]("fkdjfkdj")))

  def foo[A](somelist: List[A])(implicit m: Manifest[A]): String = {
    if (m <:< manifest[String]) {
      "its a string"
    } else {
      "its not a string"
    }
  }
}

which yields correctly:

"its a string"

and for int

object Main extends App {
  println(Main.foo(List[Int](1)))

  def foo[A](somelist: List[A])(implicit m: Manifest[A]): String = {
    if (m <:< manifest[String]) {
      "its a string"
    } else {
      "its not a string"
    }
  }
}

its not a string
Jas
  • 14,493
  • 27
  • 97
  • 148