Szukaj…


Kompozycje funkcji z wieloma kanałami

Arrow jest, niejasno mówiąc, klasą morfizmów, które składają się na podobne funkcje, zarówno w składzie szeregowym, jak i „składzie równoległym”. Chociaż jest to najbardziej interesujące jako uogólnienie funkcji, sama instancja Arrow (->) jest już całkiem przydatna. Na przykład następująca funkcja:

spaceAround :: Double -> [Double] -> Double
spaceAround x ys = minimum greater - maximum smaller
 where (greater, smaller) = partition (>x) ys

można również pisać za pomocą kombinacji strzałek:

spaceAround x = partition (>x) >>> minimum *** maximum >>> uncurry (-)

Ten rodzaj kompozycji najlepiej można wizualizować za pomocą diagramu:

                       ──── minimum ────
                   ╱           *            ╲
──── partition (>x) >>>        *        >>>  uncurry (-) ───
                   ╲           *            ╱
                       ──── maximum ──── 

Tutaj,

  • Operator >>> to po prostu odwrócona wersja zwykłego . operator kompozycji (istnieje również wersja <<< która składa się od prawej do lewej). Przesyła dane z jednego etapu przetwarzania do następnego.

  • wychodzące wskazują, że przepływ danych jest podzielony na dwa „kanały”. Pod względem typów Haskell jest to realizowane za pomocą krotek:

    partition (>x) :: [Double] -> ([Double], [Double])
    

    dzieli przepływ na dwa [Double] kanały, natomiast

    uncurry (-) :: (Double,Double) -> Double
    

    łączy dwa Double kanały.

  • *** jest operatorem kompozycji równoległej . Pozwala maximum i minimum działać niezależnie na różnych kanałach danych. W przypadku funkcji podpisem tego operatora jest

    (***) :: (b->c) -> (β->γ) -> (b,β)->(c,γ)
    

Przynajmniej w kategorii Hask (tj. W instancji Arrow (->) ) f***g nie oblicza równolegle f i g równolegle jak w różnych wątkach. Ale teoretycznie byłoby to możliwe.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow