Why scala doesn't infer type from generic type parameters?

前端 未结 1 1506
旧时难觅i
旧时难觅i 2021-01-04 23:30

Suppose this function

def func[A](data: List[A], mapper: A => String) = { 
  data.map(item => mapper(item)) 
}

Why this code doesn\'t

1条回答
  •  礼貌的吻别
    2021-01-05 00:01

    There is another way! It also happens to make for some nice syntatic sugar:

    def func[A](data: List[A])(mapper: A => String) = data map mapper
    

    which looks like:

    func(myList){
      case Left(one) => one
      case Right(_) => default
    }
    

    The reason that you can not get the type information to flow the way you'd expect is that type information in Scala is left to right. In other systems, type information is known and deduced for useage where it is defined. You sometimes have to work around these limitations but at the same time, in this case, you can get to work with something that looks akin to your own defined control structure.

    So...

    func[Int]( //I've just told the typer what the information is and it can flow to the right.
    func(list //the typer has to deduce the type and without a guide can not figure out what a => a.toString should be
    

    This is also an old "issue" you can see here SI-4773.

    Response to Q in Comment:

    If you want to have a Seq[A => B] then I'd do something similar to

    func[A, B](data: List[A])(actions: A => B*) = actions map { 
      data map
    }
    

    which is using varargs (translates to a WrappedArray, hence the map) to accept any list of commands so that you can pass is

    func(list)(_.name, _.age, _.sex, _.stalker)
    

    as far as pulling out and matching on what you've passed in:

    func[A, B](data: List[A])(actions: (String, A => B)*) = actions map { 
      case (name, f) => (name, data map f)
    }
    

    wherein you're using the case statement to pattern match and extract the tuple.

    0 讨论(0)
提交回复
热议问题