Ważne jest, aby robić z niego inne rzeczy niż po prostu extract
. Intuicyjnie, jeśli jedyną rzeczą, którą możesz zrobić, to wyodrębnić wartość, wtedy typ zawiera tylko jedną wartość, więc powielenie tej jednej wartości powoduje duplikowanie wszystkiego. Nie jest to prawda w ogóle, i nie jest prawdą w przypadku zamków błyskawicznych.
Ustawy Comonad
są tylko ustawami o kategorii w przebraniu funkcji typu w a -> b
. Ponieważ pochodzą one z kategorii, łatwiej jest o nich mówić kategoriami niż kategoriami Comonad
. extract
to tożsamość tej kategorii, a =<=
to operator kompozycji.
-- | Right-to-left 'Cokleisli' composition
(=<=) :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> c
f =<= g = f . extend g
Wiemy również, że extend f = fmap f . duplicate
, więc możemy napisać
f =<= g = f . fmap g . duplicate
Wygląda to dość łatwe do rozsądku o.Teraz wyposażyliśmy Twój typ Z
w inną funkcję, o której możemy porozmawiać. isFirst
zwróci true tylko wtedy, gdy Z
reprezentuje wartość na pozycji na liście bez niczego przed nią.
Rozważmy teraz, co się stanie, gdy użyjemy isFirst
z trzema kategoriami praw. Wydaje się, że jedyne dwa, które wydają się natychmiast mieć zastosowanie, to to, że extract
jest lewą i prawą tożsamością kompozycji według =<=
. Ponieważ obalamy to tylko, musimy znaleźć jedynie kontrprzykład. Podejrzewam, że jeden z extract =<= isFirst
lub isFirst =<= extract
zakończy się niepowodzeniem dla wejścia Z [1] 2 []
. Oba powinny być takie same, jak isFirst $ Z [1] 2 []
, czyli False
. Najpierw spróbujmy extract =<= isFirst
, co powinno się udać.
extract =<= isFirst $ Z [1] 2 []
extract . fmap isFirst . duplicate $ Z [1] 2 []
extract . fmap isFirst $ Z [] (Z [1] 2 []) []
extract $ Z [] (isFirst (Z [1] 2 [])) []
extract $ Z [] False []
False
Kiedy spróbujemy isFirst =<= extract
, nie będziemy mieli tyle szczęścia.
isFirst =<= extract $ Z [1] 2 []
isFirst . fmap extract . duplicate $ Z [1] 2 []
isFirst . fmap extract $ Z [] (Z [1] 2 []) []
isFirst $ Z [] (extract (Z [1] 2 [])) []
isFirst $ Z [] 2 []
True
Kiedy straciliśmy informacje o strukturze. W rzeczywistości straciliśmy informacje o wszystkim, co przyszło wszędzie, z wyjątkiem jednego centralnego punktu zamka błyskawicznego. Prawidłowy duplicate
miałby cały "dodatkowy zamek błyskawiczny wszędzie w kontekście utrzymującym wartość w tej lokalizacji i kontekście tej lokalizacji.
Zobaczmy, co możemy wywnioskować z tych przepisów. Niewielką ręką machając ręką na temat kategorii funkcji, widzimy, że =<= extract
jest , a to musi być funkcja tożsamości. Najwyraźniej odkrywam na nowo, w jaki sposób prawa są zapisane w dokumentacji dla Control.Category
. To pozwala nam napisać coś jak
z = (=<= extract) z
z = fmap extract . duplicate $ z
Teraz z
ma tylko jeden konstruktor, więc możemy podstawić że w
Z left x right = fmap extract . duplicate $ Z left x right
Od one rodzaj dwóch egzemplarzach, wiemy, to musi wrócić tego samego konstruktora.
Z left x right = fmap extract $ Z lefts (Z l x' r) rights
Jeśli zastosujemy fmap
do tego Z
mamy
Z left x right = Z (fmap extract lefts) (extract (Z l x' r)) (fmap extract rights)
Jeśli podzielimy to przez części konstruktora Z
mamy trzy równania
left = fmap extract lefts
x = extract (Z l x' r)
right = fmap extract rights
To mówi nam, że co najmniej wynik duplicate (Z left x right)
musi zawierać:
- lista z taką samą długość jak
left
na lewej stronie
Z
z x
w środku na środkowym
- liście z tej samej długości co
right
dla prawej strony
Co więcej, widzimy, że wartości średnie na listach po lewej i prawej stronie muszą być takie same, jak wartości oryginalne na tych listach.Biorąc pod uwagę tylko to jedno prawo wiemy wystarczająco, aby wymagać innej struktury dla wyniku duplicate
.
Być może zainteresuje Cię to pytanie o wyprowadzanie instancji komandodowych dla zamków błyskawicznych ogólnie dla każdego innego typu. http://stackoverflow.com/q/25554062/414413 Jeśli tak, sprawdź ekstensywne rozwiązanie dla hodowcy z częściowymi równaniami różniczkowymi lub moje rozwiązanie z drugą pochodną. – Cirdec
Dzięki za link, przewinąłem go, próbując znaleźć odpowiedź na moje pytanie, ale teraz, kiedy poleciłeś to wyraźnie, widzę, że ma mnóstwo nowych rzeczy, o które mógłbym się zastanowić. Z pewnością zajrzę w to. – Jackie