You can use a short tail-recursive function such as the following.
The idea is to use next to store the "next List of Drinks to append to the result" and acc to accumulate these Lists of Drinks, into a List of List of Drinks.
The base case is an empty list, in which the results are returned. Otherwise, either the next drink matches the next sublist (add it to this sublist), or it doesn't (add the sublist to the result and start a new sublist with the new drink).
Note that :+ is a List method which gives back a new List with the specified item appended.
@tailrec
def get(list:List[Drink],
next:List[Drink]=List(),
acc: List[List[Drink]]=List()): List[List[Drink]] =
list match {
case Nil => acc :+ next // dump final results
case head :: tail =>
if (next.isEmpty || next.head.getClass == head.getClass) get(tail, next :+ head, acc)
else get(tail, List(head), acc :+ next)
}
println(get(drinks))
Result:
List(List(Coke, Coke), List(Pepsi), List(Coke), List(Pepsi, Pepsi))
Note, noticed that jwvh has a correct answer too, with proper pattern matching instead of these conditionals. Using the head method on a List can be unsafe (or hard for the compiler to determine the safety), but this approach may be more concise especially if there are many kinds of Drink.
If you want to avoid using head directly, you can write this, which I find more confusing:
...
if (next.headOption.map(h => h.getClass == head.getClass).getOrElse(true)) get(tail, next :+ head, acc)
...