0

I am trying to write a function that counts the number of elements in an array of elements of type T that pass a test of type T=>Boolean.

What I have so far is:

     def countPass[T](elem: Array[T]) = {
        var count = 0
        for(x <- elem) 
            x match { 
                case x: T => count += 1
            }
        count
    }

    //TEST
    println(countPass[Boolean](Array(true, 52, "test")))

I'm getting a couple of errors, the first one is:

combinators.scala:45: warning: abstract type pattern T is unchecked since
it is eliminated by erasure
                        case x: T => count += 1
                                ^

The next error is:

combinators.scala:54: error: type mismatch;
 found   : Int(52)
 required: Boolean
    println(countPass[Boolean](Array(true, 52, "test")))
                                           ^
combinators.scala:54: error: type mismatch;
 found   : String("test")
 required: Boolean
    println(countPass[Boolean](Array(true, 52, "test")))
                                               ^

I'm not sure about whats happening with the first error, but with the second error it throws an exception anytime its not a boolean. I don't want that to happen because I'm just counting the amount of elements of type T are in the array.

Question: How should I refactor my code to fix both of these errors?

3 Answers 3

7

The trick is using ClassTag. A better way to accomplish your request is as follows:

import scala.reflect.ClassTag

object Main extends App {

  val array: Array[Any] = Array("string1", "string2", "string3", true, false, 13)

  def countPass[Other: ClassTag](array: Array[Any]): Int = {
    array.collect { case x: Other => x }.length
  }

  println(s"countPass String = ${countPass[String](array)}")
  println(s"countPass Boolean = ${countPass[Boolean](array)}")
  println(s"countPass Int = ${countPass[Int](array)}")
}

You can read this to learn more about ClassTag and TypeTag

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

3 Comments

This is very far from what I initially have and what I wanted to accomplish. However, your solution did make me realize I should have used 'Any' inside of the array parameter.. But I'm still having an issue with the first error
Since your array contains different types, your array's type must support all of them. Therefore, you should define an Array[Any].
Make sure that you import import scala.reflect.ClassTag. Additionally, you can read this: medium.com/@sinisalouc/…
0

So I found out a way that works, but not exactly what I wanted.

     def countPass[T](elem: Array[T]) = {
        var count = 0
        for(x <- elem) 
            x match { 
                case _: Boolean => count += 1
                case _ => None
            }
        count
    }

    //TEST
    println(countPass[Any](Array(true, 5, "test", false, false)))

The issue was I needed to pass Any into the array because I have different types in there. Additionally, I needed to change my cases a bit and add the default case.

This works perfectly, but I wanted something more like this. This does NOT work because of the same error specified above

    def countPass[T](elem: Array[Any]) = {
        var count = 0
        for(x <- elem) 
            x match { 
                case _: T => count += 1   //Here is the error
                case _ => None
            }
        count
    }

    //TEST
    println(countPass[Boolean](Array(true, 5, "test", false, false)))

For some reason I cannot do _: T as my case or I get this error:

combinators.scala:44: warning: abstract type pattern T is unchecked since 
it is eliminated by erasure
                case _: T => count += 1

1 Comment

To match _: T (correctly), you need a ClassTag[T], as fcat's answer says.
0

You can directly use the method count

def countPass[T: ClassTag](elem: Array[Any]): Int = elem.count{
    case _ : T => true
    case _ => false
}

2 Comments

This doesn't do what the OP wants, which is a countPass that counts elements of the generic type T, not a fixed Boolean. If you replace your Boolean with T, you get the OP's error.
you are right, I misunderstood the question... I've fixed the solution

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.