2015-07-05 35 views
16

ich this blog bin nach, einen einfachen HTTP-Server in Haskell zu schreiben,Control.Category, was bedeutet >>> und <<<?

Verwendung von >>> mir nicht klar ist. Was macht dieses Code-Snippet?

handleHttpConnection r c = runKleisli 
    (receiveRequest >>> handleRequest r >>> handleResponse) c >> 
    close c 

Similary auf this link bin ich <<< sehen

let h =  arr (++ "!") 
      <<< arr foo 
      <<< Kleisli bar 
      <<< arr id 

Was tut <<< und >>>? (Hackage document ist sehr knapp und konnte nicht viel aus ihm heraus.)

+1

Dieser Blog hat einen [link] (https://wiki.haskell.org/Arrow_tutorial#Kleisli_Arrows) zu einem Artikel über Kleisli Pfeile, der nützlich scheint. Ich glaube, dass diese beiden Operatoren eine Art von Funktionszusammensetzung darstellen (für Pfeile, die Funktionen sind). Für andere Arten von Pfeilen bin ich mir nicht sicher, da Pfeile mir etwas fremd sind. – jpaugh

Antwort

20

Als Hackage und/oder Hoogle wird Ihnen sagen,

(>>>) :: Category k => a`k`b -> b`k`c -> a`k`c 
(<<<) :: Category k => b`k`c -> a`k`b -> a`k`c 

Beachten Sie, dass diese ist eigentlich die gleiche wie

(.) :: Category k => b`k`c -> a`k`b -> a`k`c 

oder in seiner Prelude Form, spezialisiert auf die Hask Kategorie von Funktionen,

(.) ::    (b->c) -> (a->b) -> (a->c) 

Also, <<< und >>> einfach komponieren Funktionen oder allgemeiner Morphismen/Pfeile.

<<< komponiert in der gleichen Richtung wie die bekannten ., während die Argumente >>> Flips so dass “ Daten von links nach rechts fließen ”.


Nun, was Pfeil Zusammensetzung bedeutet, für andere Kategorien Hask, hängt natürlich von der Kategorie ab. Kleisli IO ein leicht Beispiel zu verstehen: sagen wir

pipe :: Double -> String 
pipe = show . sqrt . (+2) . abs 

Wie gesagt, dies kann auch

pipe = abs >>> (+2) >>> sqrt >>> show 

Jetzt haben, eine reine Funktion geschrieben werden, wenn Sie primitive IO-Protokollierung (wie Sie hinzufügen möchten könnte in einer imperativen Sprache) können Sie

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 

Damit vorstellen möchten, können Sie

0 definieren

in genau die gleiche Art und Weise wie zuvor, das heißt

pipe' = abs' >>> add2' >>> sqrt' >>> show' 

Aber Sie werden jetzt die Zwischenergebnisse ausgedruckt als Nebenwirkung erhalten.

+0

das ist ein schönes Beispiel ... danke ... warum sollte jemand 'zeigen. sqrt. (+2). abs statt 'show $ sqrt $ (+2) $ abs n'. Ich weiß, dot '.' dreht sich alles um eine Funktionszusammensetzung, aber löst es jedes Problem, das' $ 'nicht löst? –

+2

@MadhavanKumar: Nun, das ist in der Tat ein hervorragendes Beispiel für das, was '$' nicht löst: Es kann nicht verallgemeinert werden, um in beliebigen Kategorien zu arbeiten. ([Einige Kategorien haben eine Verallgemeinerung von '$', aber die meisten nicht - einschließlich 'Kleisli'] (http://stackoverflow.com/questions/31118949/generalising-like-control-category-generalisations/31120454#31120454) .) Abgesehen davon ist der point-free Stil oft prägnanter, kann etwas einfacher refaktoriert werden und erfordert nicht die Einführung eines Variablennamens ... dies sind jedoch nicht immer Vorteile; manchmal ist Punktfreiheit schwieriger zu verstehen ("sinnloser Code"). – leftaroundabout

+1

Dann sind '<=<' and '> =>' auch Sonderfälle von '<<<' and '> >>', die für Monaden funktionieren? –

Verwandte Themen