Ricerca…


Composizioni di funzioni con più canali

Arrow è, vagamente parlando, la classe dei morfismi che compongono come funzioni, sia con composizione seriale che con "composizione parallela". Mentre è più interessante come generalizzazione delle funzioni, l'istanza Arrow (->) è già abbastanza utile. Ad esempio, la seguente funzione:

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

può anche essere scritto con i combinatori di frecce:

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

Questo tipo di composizione può essere meglio visualizzato con un diagramma:

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

Qui,

  • L' operatore >>> è solo una versione capovolta dell'ordinario . operatore di composizione (c'è anche una versione <<< che compone da destra a sinistra). Conduce i dati da un passaggio di elaborazione a quello successivo.

  • il indica che il flusso di dati è diviso in due "canali". In termini di tipi Haskell, questo è realizzato con tuple:

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

    divide il flusso in due canali [Double] , mentre

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

    unisce due canali Double .

  • *** è l'operatore di composizione parallela . Consente al maximum e al minimum operare in modo indipendente su diversi canali dei dati. Per le funzioni, la firma di questo operatore è

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

Almeno nella categoria Hask (cioè nell'istanza Arrow (->) ), f***g realtà non calcola f e g in parallelo come in, su thread diversi. Ciò sarebbe teoricamente possibile, però.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow