2017-10-10 3 views
1

j'ai une fonction de travailleurio-Streams partitionEithers

worker :: a -> Either b c 

et je veux l'appliquer à un flux de a et produire 2 flux de b et c et traiter ces flux plus loin. Par exemple, je veux accumuler c dans un Map (essentiellement pour plier le flux) et la sortie b à stderr.

Comment puis-je réaliser ceci avec io-streams? Il semble que je ne peux pas appeler connect deux fois. Donc, je dois le mettre avant la séparation, de sorte que le partitionnement fonctionnera sur OutputStream dans un « contravariante » chemin:

contrapartitionEithers 
    :: OutputStream b -> OutputStream c -> IO (OutputStream (Either b c)) 

est-il implémentable? Si non, comment peut-on faire la tâche à portée de main? Si oui, est en quelque sorte "dual" à System.IO.Streams.zip?

System.IO.Streams.zip 
    :: InputStream a -> InputStream b -> IO (InputStream (a, b)) 

Répondre

2

Parfois, la bonne question contient la réponse. Donc c'est possible en effet:

contrapartitionEithers 
    :: OutputStream b -> OutputStream c -> IO (OutputStream (Either b c)) 
contrapartitionEithers b c = makeOutputStream $ maybe 
    (writeTo b Nothing >> writeTo c Nothing) 
    (either (writeTo b . Just) (writeTo c . Just))