Search code examples
scalatypesshapelesstype-level-computationscala-2.13

Implement function which output type is depend on input type


Let imagine I have the following traits/classes hierarchy ( scala 2.13 )

trait In
trait Out

case class In1() extends In
case class In2() extends In

case class Out1() extends Out
case class Out11() extends Out
case class Out2() extends Out

I'd like to write function that:

  • In the case where In1 was sent as a param will only allow the return of Out1 or Out11 object
  • In the case where In2 was sent as a param will only allow the return of Out2 object
  • Will check it on compile time

Unfortunately, I wasn't able to achieve it on my own even using external libs.

Could you please help or clarify if it possible at all ?


Solution

  • There are multiple ways to do what you are asking, but it is not clear which one would be more suitable to your use case than others ... because you didn't really describe you use case :)

    This one is, probably, the simplest/most straight-forward:

    trait O
    trait O1 extends O
    trait O2 extends O
    
    trait In[T <: O] 
    trait Out
    
    case class In1() extends In[O1]
    case class In2() extends In[O2]
    
    case class Out1() extends Out with O1
    case class Out11() extends Out with O1
    case class Out2() extends Out with O2
    
    def foo[T <: O](in: In[T]): T = ???