Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a structural type with generic parameters?

I have two case classes

case class StringCaseClass(argument: String)

case class IntCaseClass(argument: Int)

I want to define a structural type which will match the companion object of both of these

type HasApply1 {
  def apply[A, R](argument: A): R
}

This will compile fine, but when I try to use it like this

def method(caseClass: HasApply1) {
  // whatever
}

method(StringCaseClass)

I will get a compiler error

found   : StringCaseClass.type
required: WithApply1
            (which expands to)  AnyRef{def apply[A, R](string: A): R}

Is there any way of accomplishing this? If I redefine the structural type to have concrete types for A and R it will compile correctly, but then I lose the flexiblity

like image 881
shinyhappydan Avatar asked Mar 24 '13 13:03

shinyhappydan


People also ask

Which types can be used as arguments of a generic type?

The actual type arguments of a generic type are. reference types, wildcards, or. parameterized types (i.e. instantiations of other generic types).

How do you pass a generic class as parameter in TypeScript?

Assigning Generic ParametersBy passing in the type with the <number> code, you are explicitly letting TypeScript know that you want the generic type parameter T of the identity function to be of type number . This will enforce the number type as the argument and the return value.

How do you provide the Parametrized type for a generic?

In order to use a generic type we must provide one type argument per type parameter that was declared for the generic type. The type argument list is a comma separated list that is delimited by angle brackets and follows the type name. The result is a so-called parameterized type.

How many type parameters can be used in a generic class?

Multiple parameters You can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.


1 Answers

@aloiscochard's comment is almost there. What he forgot to mention is that case class companion objects already implement the appropriate FunctionN trait, so you can simply do this,

scala> case class StringCaseClass(argument: String)
defined class StringCaseClass

scala> case class IntCaseClass(argument: Int)
defined class IntCaseClass

scala> def method[A, R](caseClass: A => R, a: A) = caseClass(a)
method: [A, R](caseClass: A => R, a: A)R

scala> method(StringCaseClass, "foo")
res0: StringCaseClass = StringCaseClass(foo)

scala> method(IntCaseClass, 23)
res1: IntCaseClass = IntCaseClass(23)
like image 179
Miles Sabin Avatar answered Nov 15 '22 06:11

Miles Sabin