Jest to doskonały przypadek użycia dla applicative style. Można wymienić cały fragment (po imporcie Control.Applicative
) z
Node <$> numberNode x <*> numberTree t1 <*> numberTree t2
myśleć o stylu aplikacyjnej (używając <$>
i <*>
) jako „Podnoszenie” aplikacji funkcji tak to działa na funktorów również. Jeśli mentalnie zignorujesz <$>
i <*>
, wygląda to całkiem podobnie do zwykłej aplikacji!
Styl aplikacyjny jest przydatny, gdy masz czystą funkcję i chcesz nadać jej nieczyste argumenty (lub jakiekolwiek argumenty funktora) - w zasadzie, gdy chcesz zrobić to, co określono w pytaniu!
typu podpis <$>
jest
(<$>) :: Functor f => (a -> b) -> f a -> f b
co oznacza, że ma czystej funkcji (w tym przypadku Node
) i wartość funktora (w tym przypadku numberNode x
) i tworzy nową funkcję owinięty "wewnątrz" funktora. Możesz dodać kolejne argumenty do tej funkcji z <*>
, który ma podpis typu
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Jak widać, jest to bardzo podobne do <$>
tylko to działa nawet wtedy, gdy funkcja jest owinięty „wewnątrz” funktorem.
Dziękuję za wciśnięcie mojej głowy o tę ścianę. Nie wiem dlaczego, ale po prostu nie miałem prostego rozwiązania. – floAr
Nie ma za co! –