Вывод типа Scala работает по одному блоку параметров за раз. Nil
без какого-либо другого контекста не имеет определенного типа, поэтому выбран наиболее ограничивающий тип (Nothing
).
Он также не может определить тип возвращаемого значения функции, поскольку тип возвращаемого значения зависит от типа Nil
. В общем, выбраться из такого рода цикличности довольно сложно (если вы не укажете, что имеете в виду).
Есть несколько приемов, которые вы можете применить, чтобы сделать вещи менее громоздкими.
Во-первых, сигнатура типа fold
имеет только тип коллекции, поэтому, если вы можете использовать этот тип сгиба, вы можете обойти проблему. Например, вы можете написать свой собственный реверс-сглаживание:
List(List(1),List(2),List(3)).fold(Nil)( (x,y) => y ::: x )
Во-вторых, если вы создаете новую коллекцию того же типа, часто проще использовать существующую коллекцию для создания пустой, чем пытаться подключать типы для пустой коллекции. Это особенно легко, если у вас где-то определена труба:
class PipeAnything[A](a: A) { def |>[B](f: A => B) = f(a) }
implicit def anything_can_be_piped[A](a: A) = new PipeAnything(a)
List(1,2,3) |> { x => x.foldLeft(x.take(0))( (y,z) => z :: y ) }
Наконец, не забывайте, что вы можете довольно легко определить свои собственные методы, которые могут сделать что-то в соответствии с вашими типами, даже если вам придется использовать немного хитрости, чтобы заставить его работать:
def foldMe[A,B](example: A, list: List[B])(f: (List[A],B) => List[A]) = {
(List(example).take(0) /: list)(f)
}
scala> foldMe( ("",0), List("fish","wish","dish") )( (x,y) => (y.take(1), y.length) :: x )
res40: List[(java.lang.String, Int)] = List((d,4), (w,4), (f,4))
Здесь, обратите внимание, что пример не ноль , а скорее используется только как пример вещи с нужным вам типом.