Question

I am trying currently trying to solve some Scala problem set for getting to know with the language. I am stuck with problem 11 where my solution will not compile. My question is: Why is this illegal in Scala?

def countPackSingle[A](list: List[A]): List[Any] = {
  pack(list) map {ls => {
    case head :: Nil => head
    case head :: tail => List(tail.size + 1, head)
  }}
}

IntelliJ is happy about this definition, but the compiler complains:

missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)

Expected type was: ?

pack(list) map {ls => {
                      ^

I do not really get what this message is trying to tell me. Can the scala compiler not infere the type of ls? When I specify the type by ls: List[A], the problem however remains.

At this occasion: Why can I specify the type for the argument ls when using curly braces { } but not when using parenthesises ( )? Until today, I am looking for a good resource explaining the difference in Scala. So far, I believed it only makes a real difference when using the literals to create parial functions via `case and on some other rare occasions.

Thanks for help!

Was it helpful?

Solution

This structure:

{
  case head :: Nil => head
  case head :: tail => List(tail.size + 1, head)
}

is a syntactic sugar for a partial function, that's why compiler throws you this message, scalac thinks that you are trying to make a PartilFunction[List[A], List[A]]. To fix this issue you have three ways:

1) Complete this to pattern matching construct:

pack(list) map { ls => ls match {
    case head :: Nil => head
    case head :: tail => List(tail.size + 1, head)
  }
}

2) Use underscore syntax:

pack(list) map { _ match {
    case head :: Nil => head
    case head :: tail => List(tail.size + 1, head)
  }
}

which is actually the same. Now, if you want, you can ascribe a type for ls, but scala can successfully infer it.

3) Use inline syntax:

pack(list) map {
  case head :: Nil => head
  case head :: tail => List(tail.size + 1, head)
}

It is possible because PartialFunction is a subclass of Function, so it is possible to use partial function directly instead of plain function.

And you have no point in the result type List[Any]. 1) this type is not good, cause you loose all your type information and 2) you function is not tailrecursive, so you can drop it and let scalac infer it for you

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top