Если вы посмотрите на тип подписи fold
:
fold[A1 >: Char](z: A1)(op: (A1, A1) ⇒ A1): A1
вы увидите, что он работает только на супертипов Char
с, поэтому делает невозможным ваше выражение и компилятор бросает ошибку.
foldLeft
однако позволяет использовать тип результата B
foldLeft[B](z: B)(op: (B, Char) ⇒ B): B
Это позволяет записать текущее выражение.
Чтобы резюмировать: fold
ожидает Char
в качестве своего аргумента семян (при предоставлении 1L
в качестве семени компилятор будет жаловаться), в то время как foldLeft
ожидает результирующий тип вашей op
функции.
Update:
s.fold(1L){(z, i) => z}
также считается правильным компилятором. Это связано с тем, что Char
и Long
делятся супертипом AnyVal
. С fold
ожидает, что супертип Char
также обеспечит AnyVal
. Это также причина, по которой компилятор жалуется, что не может найти функцию *
, потому что она не определена для типа AnyVal
.
Update 2:
Если вы действительно хотите использовать fold
вместо foldLeft
вам придется карту s
к послед [Long] заранее. То есть:
s.map(_.toLong).fold(1L){(z, i) => z*i} //returns 9415087488
Пожалуйста, вы можете дать мне пример Но, как я могу проверить, выражение s.fold (1L) {(г, г) => г} также правильно, и семя 1L, а? а не char, почему это тоже правильно? – Coinnigh
Какой пример вы хотели бы видеть? –
Когда я предоставляю 1L в качестве своего семени, компилятор не жаловался, и результат 1 – Coinnigh