Come Hackage e/o Hoogle vi dirà,
(>>>) :: Category k => a`k`b -> b`k`c -> a`k`c
(<<<) :: Category k => b`k`c -> a`k`b -> a`k`c
Si osservi che quest'ultimo è in realtà lo stesso di
(.) :: Category k => b`k`c -> a`k`b -> a`k`c
o, nella sua forma Prelude
, specializzato per il Hask categoria di funzioni,
(.) :: (b->c) -> (a->b) -> (a->c)
Quindi, <<<
e >>>
compongono semplicemente funzioni, o più in generale morfismi/frecce.
<<<
compone nella stessa direzione del familiare .
, mentre >>>
ribalta gli argomenti in modo che i dati “ cassa da sinistra a destra ”.
Ora, che cosa freccia composizione significa, per le categorie diverse da Hask, dipende ovviamente dalla categoria. Kleisli IO
è un facile da capire esempio: dire che abbiamo una funzione di pura
pipe :: Double -> String
pipe = show . sqrt . (+2) . abs
Come ho detto, questo può anche essere scritta
pipe = abs >>> (+2) >>> sqrt >>> show
Ora, se si desidera aggiungere primitiva IO legname (come te potrebbe in un linguaggio imperativo), è possibile introdurre
type (-|>) = Kleisli IO
abs', add2', sqrt' :: Num a => a -|> a
show' :: Show a => a -|> String
abs' = Kleisli $ \x -> do putStrLn ("Absolute of "++show x++"...")
return $ abs x
add2' = Kleisli $ \x -> do putStrLn ("Add 2 to "++show x++"...")
return $ x + 2
sqrt' = Kleisli $ \x -> do putStrLn ("Square root of "++show x++"...")
return $ sqrt x
show' = Kleisli $ \x -> do putStrLn ("Show "++show x++"...")
return $ show x
Con questo, è possibile definire
pipe' :: Double -|> String
in esattamente allo stesso modo di prima, vale a dire
pipe' = abs' >>> add2' >>> sqrt' >>> show'
Ma avrete ora ottenere i risultati intermedi stampati come un effetto collaterale.
Quel blog ha un [collegamento] (https://wiki.haskell.org/Arrow_tutorial#Kleisli_Arrows) a un articolo sulle frecce di Kleisli che sembra utile. Credo che questi due operatori rappresentino una sorta di composizione di funzioni (per le frecce che sono funzioni). Per altri tipi di frecce, non ne sono sicuro, poiché le frecce sono un po 'strane per me. – jpaugh