Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 57 additions & 17 deletions _pl/tour/multiple-parameter-lists.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,77 @@ discourse: false

partof: scala-tour

num: 9
num: 10
language: pl
next-page: case-classes
previous-page: nested-functions
---

Funkcja może określić dowolną ilość list parametrów. Kiedy jest ona wywołana dla mniejszej liczby niż zostało to zdefiniowane, zwraca funkcję pobierającą dalsze listy parametrów jako jej argument.
Metoda może określać dowolną liczbę list parametrów.
W sytuacji, kiedy jest ona wywołana dla mniejszej liczby list parametrów niż zostało to zdefiniowane, zwracana jest funkcja oczekująca pozostałych list parametrów jako argumentów.

Przykład rozwijania funkcji:
Dla przykładu przyjrzyjmy się metodzie `foldLeft` zdefiniowanej w [Traversable](/overviews/collections/trait-traversable.html) z kolekcji w Scali:

```
def foldLeft[B](z: B)(op: (B, A) => B): B
```

Metoda `foldLeft` stosuje binarny operator `op` na wartości początkowej `z` oraz wszystkich elementach zawartych w aktualnym obiekcie `Traversable` - idąc od lewej do prawej strony.
Poniżej omówiony jest przykład użycia.

Zaczynając od początkowej wartości 0, funkcja `foldLeft` stosuje funkcję `(m, n) => m + n` na każdym elemencie listy oraz poprzedniej zakumulowanej wartości.

{% scalafiddle %}
```tut
object CurryTest extends App {
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val res = numbers.foldLeft(0)((m, n) => m + n)
println(res) // 55
```
{% endscalafiddle %}

Metody z wieloma listami parametrów mają bardziej dosadną składnię wywoływania, dlatego powinny być używane oszczędnie.
Sugerowane przypadki użycia obejmują:

#### Funkcja jako pojedynczy parametr

def filter(xs: List[Int], p: Int => Boolean): List[Int] =
if (xs.isEmpty) xs
else if (p(xs.head)) xs.head :: filter(xs.tail, p)
else filter(xs.tail, p)
W przypadku funkcji jako pojedynczego parametru, tak jak w przypadku `op` z `foldLeft` powyżej, wiele list parametrów pozwala na bardziej zwięzłą składnię przy przekazywaniu funkcji anonimowej do metody.
Bez wielu list parametrów kod wyglądałby w następujący sposób:

```
numbers.foldLeft(0, {(m: Int, n: Int) => m + n})
```

def modN(n: Int)(x: Int) = ((x % n) == 0)
Zauważ, że użycie wielu list parametrów pozwala na wykorzystanie wnioskowania typów, co z kolei czyni kod bardziej zwięzłym (jak pokazano poniżej).
Używając standardowej definicji metody, nie byłoby to możliwe.

val nums = List(1, 2, 3, 4, 5, 6, 7, 8)
println(filter(nums, modN(2)))
println(filter(nums, modN(3)))
}
```
numbers.foldLeft(0)(_ + _)
```

_Uwaga: metoda `modN` jest częściowo zastosowana dla dwóch wywołań `filter`, gdyż jest wywołana tylko dla jej pierwszego argumentu. Wyrażenie `modN(2)` zwraca funkcję typu `Int => Boolean` - stąd też może być przekazane jako drugi argument funkcji `filter`._
Powyższe wyrażenie `numbers.foldLeft(0)(_ + _)` pozwala trwale ustawić parametr `z` i przekazywać dalej częściową funkcję (partial function), tak jak pokazano to poniżej:

Wynik działania powyższego programu:
```tut
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val numberFunc = numbers.foldLeft(List[Int]())_

val squares = numberFunc((xs, x) => xs:+ x*x)
print(squares.toString()) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

val cubes = numberFunc((xs, x) => xs:+ x*x*x)
print(cubes.toString()) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000)
```
List(2,4,6,8)
List(3,6)

Podsumowując, `foldLeft` oraz `foldRight` mogą być używane w dowolnej z poniższych postaci:

```tut
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

numbers.foldLeft(0)((sum, item) => sum + item) // postać ogólna
numbers.foldRight(0)((sum, item) => sum + item) // postać ogólna

numbers.foldLeft(0)(_+_) // postać rozwijana (curried)
numbers.foldRight(0)(_+_) // postać rozwijana (curried)

(0 /: numbers)(_+_) // Alternatywy sposób wywołania foldLeft
(numbers :\ 0)(_+_) // Alternatywy sposób wywołania foldRight
```
4 changes: 3 additions & 1 deletion _tour/multiple-parameter-lists.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ def foldLeft[B](z: B)(op: (B, A) => B): B

Starting with an initial value of 0, `foldLeft` here applies the function `(m, n) => m + n` to each element in the List and the previous accumulated value.

{% scalafiddle %}
```tut
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val res = numbers.foldLeft(0)((m, n) => m + n)
print(res) // 55
println(res) // 55
```
{% endscalafiddle %}

Multiple parameter lists have a more verbose invocation syntax; and hence should be used sparingly. Suggested use cases include:

Expand Down