Wyjaśnienie w https://github.com/hemanth/functional-programming-jargon jest niestety mało dokładne.
spiczasty funktor jest naprawdę funktor F
razem z funkcją of
zdefiniowanej dla każdego typu a
i wysyłanie wartości x
typu a
na wartość of(x)
typu F a
. W Hindley-Milner signature wygląda to tak:
of :: a -> F a
Na przykład, funktor Array jest wskazał of = x => [x]
, określona dla każdej wartości x
dowolnego typu a
.
Ponadto, funkcja of
(lub dokładniej, zbiór funkcji of
jak masz jeden dla każdego typu a
) musi być naturalna transformacja z funktora tożsamości w F
. Co oznacza, że of
wartości funkcji jest równa of
argumentu odwzorowanym przez tę samą funkcję:
of(f(x)) === of(x).map(f)
Na przykład, w przykładzie Array masz
[f(x)] === [x].map(f),
tak x => [x]
jest rzeczywiście naturalny przemiana.
Ale można też wziąć
of = x => [x, x]
[f(x), f(x)] === [x, x].map(f)
który jest inny szpiczasty funktor, nawet jeżeli funktor na map
pozostaje taka sama. (Zauważ, że w każdym przypadku masz bardzo specjalne tablice jako wartości of(x)
.)
Nie można jednak wziąć np.
of = x => [x, 0]
[f(x), 0] !== [x, 0].map(f)
Teraz
var grid = Grid.of({ width: 2, height: 2, list: [1, 2, 3, 4] })
jest zupelnie zwraca Twój obiekt przeszedł owinięty w Grid
. Następnie możesz zmapować swoją grid
z jakąkolwiek zwykłą funkcją f
z czystych obiektów na zwykłe obiekty, a wynik będzie taki sam jak zastosowanie f
i zawijanie do Grid
, z powodu prawa naturalnego przekształcania. Zauważ, że w ten sposób możesz także zadzwonić pod numer Grid.of
z dowolną inną wartością, taką jak Grid.of({width: 2})
z nawet Grid.of(2)
. Alternatywnie można ograniczyć typy, dla których zdefiniowano Grid.of
, a następnie wartość musi być dozwolona tylko dla określonego typu.
Ten jest nieco kłopotliwe:
Grid.of(2, 2, [1, 2, 3, 4])
Dotyczy Grid.of
kilka argumentów.Ponieważ Grid.of
jest z definicji funkcją tylko jednego argumentu, wynikiem będzie Grid.of(2)
, co może nie być tym, czego potrzebujesz. Jeśli naprawdę chcesz karmić wszystkie wartości, prawdopodobnie chcesz napisać
Grid.of([2, 2, [1, 2, 3, 4]])
Alternatywnie, można przedłużyć Grid.of
do wielu argumentów przez pre-owijając je do tablicy wewnętrznie, a następnie zastosowanie Grid.of
. To naprawdę zależy od tego, czego szukasz.
Aby zapoznać się z rzeczywistym przykładem użycia, zobacz np. here gdzie "Nudne" zadanie jest zdefiniowane przez Task.of
z wartości zwykłej. Z drugiej strony, bardziej interesujące jest zadanie here z funkcją, której nie można uzyskać z Task.of
. Ważne jest jednak, że oba zadania mogą być używane z tym samym jednolitym interfejsem, jak pokazano na obu przykładach.
Należy również zauważyć, że w tych przykładach nie stosuje się funktorów aplikacyjnych, więc nadal istnieją zastosowania wskazanych funktorów bez zastosowania.
co to jest "Foo.of"? miałeś na myśli Array.of? Pomyślałem, że od wersji Es2015 tylko Array i * TypedArray * miały 'of' –
. Jaka jest twoja oczekiwana wydajność? Nie całkiem rozumiem. – Leo
Podaj przykład swoich danych wejściowych i oczekiwanej wynikowej zawartości tablicy - w tej postaci zmieszałeś mnie z 'Foo' –