2015-10-21 10 views
7

Hier ist das Diagramm Effect im offiziellen Tutorial von pipes Paket zur Verfügung gestellt.Wie kommt es, dass "Effect" nur zwei Einläufe anstatt aller Flüsse abschließt?

type Effect = Proxy X()() X 

    Upstream | Downstream 
    +---------+ 
    |   | 
X <==  <==() 
    |   | 
() ==>  ==> X 
    | | | 
    +----|----+ 
      v 
      r 

Da Effect hat keinen Datenfluß, erwarte ich es nur Proxy X X X X zu sein, alle Strömungen abdichten. Aber stattdessen erlaubt es die zwei In-Flows. Gibt es dafür einen besonderen Grund? Wenn ich nur schreiben, was ein Effect normalerweise der Fall ist, mit Unterschrift Proxy X X X X, kann es den Compiler übergeben völlig in Ordnung:

myMonad :: Proxy X X X X IO() 
myMonad = do 
    a <- lift $ getLine 
    lift $ print a 
    return() 

Warum können wir nicht run so etwas?

Antwort

1

Sie können laufen myMonad aus Ihrem Beispiel, indem nur die bestehende Definition von runEffect nehmen und seine Art zu verallgemeinern etwas:

import Pipes (lift) 
import Pipes.Core (closed) 
import Pipes.Internal 

type Effect' a b = Proxy X a b X 

-- Definition copied straight from Pipes.Core, type generalized to Effect' 
runEffect' :: Monad m => Effect' a b m r -> m r 
runEffect' = go 
    where 
    go p = case p of 
     Request v _ -> closed v 
     Respond v _ -> closed v 
     M  m -> m >>= go 
     Pure r -> return r 

eff :: Effect' X X IO() 
eff = do 
    a <- lift $ getLine 
    lift $ print a 
    return() 

main :: IO() 
main = runEffect' eff