Sök…


Funktionskompositioner med flera kanaler

Arrow är vagt talat klassen av morfismer som komponerar liknande funktioner, med både seriekomposition och "parallellkomposition". Även om det är mest intressant som en generalisering av funktioner, är själva Arrow (->) redan ganska användbart. Till exempel följande funktion:

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

kan också skrivas med pilkombinationer:

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

Denna typ av komposition kan bäst visualiseras med ett diagram:

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

Här,

  • >>> operatören är bara en vänd version av det vanliga . kompositionsoperatör (det finns också en <<< version som komponerar höger till vänster). Det rör data från ett behandlingssteg till nästa.

  • den indikerar att dataflödet är uppdelat i två "kanaler". När det gäller Haskell-typer realiseras detta med tuples:

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

    delar upp flödet i två [Double] kanaler, medan

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

    sammanfogar två Double kanaler.

  • *** är den parallella sammansättningsoperatören. Det låter maximum och minimum fungera oberoende på olika datakanaler. För funktioner är denna operatørs signatur

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

Åtminstone i Hask- kategorin (dvs i Arrow (->) -instansen) beräknar f f***g faktiskt inte f och g parallellt som i, på olika trådar. Detta skulle dock teoretiskt vara möjligt.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow