2014-12-15 11 views
10

Non riesco a ottenere un semplice esempio di scalaz in esecuzione, la lettura da TCP e la scrittura su std out.Come leggere da TCP e scrivere su stdout?

val src = tcp.reads(1024) 
val addr = new InetSocketAddress(12345) 
val p = tcp.server(addr, concurrentRequests = 1) { 
    srC++ tcp.lift(io.stdOutLines) 
} 
p.run.run 

Si siede solo lì, non stampa nulla.

Ho anche provato diverse modalità utilizzando to, sempre con la formula magica tcp.lift per ottenere un Process[Connection, A], tra cui

tcp.server(addr, concurrentRequests = 1)(src) map (_ to tcp.lift(io.stdOutLines)) 

che non ha nemmeno la compilazione.

Ho bisogno di wye i flussi di origine e di stampa insieme? Un esempio che ho trovato sul original pull request per tcp sostituendo nio sembrava indicare questo, ma wye non sembra più esistere su Process, quindi la confusione regna purtroppo.


Modifica si scopre che, oltre ai problemi di tipo spiegati da Paolo, è inoltre necessario per eseguire i processi interni "manualmente", per esempio facendo p.map(_.run.run).run.run. Non credo che sia il modo idiomatico per farlo, ma funziona.

risposta

5

È necessario passare src attraverso il sink per scrivere effettivamente qualcosa. Credo che questo dovrebbe farlo:

import scalaz.stream.{io,tcp,text} 
import scalaz.stream.tcp.syntax._ 

val p = tcp.server(addr, concurrentRequests = 1) { 
    tcp.reads(1024).pipe(text.utf8Decode) through tcp.lift(io.stdOutLines) 
} 
p.run.run 

L'espressione srC++ tcp.lift(io.stdOutLines) in realtà dovrebbe essere un errore di tipo. Il tipo di tcp.reads(1024) è Process[Connection,ByteVector] e il tipo di tcp.lift(io.stdOutLines) è Process[Connection, String => Task[Unit]]. L'aggiunta di questi due processi non ha senso, e l'unica ragione per cui i tipografi sono dovuti alla covarianza di Process[+F[_],+O]. Scala sta "utilmente" deducendo Any quando si aggiungono due processi con tipi di output non correlati.

Una versione futura di scalaz-stream può aggiungere un vincolo sulla ++ e altre funzioni che sfruttano covarianza per assicurarsi che l'estremo superiore che viene calcolata non è qualcosa di inutile come Any o Serializable. Ciò farebbe molto per prevenire errori come questo. Nel frattempo, assicurati di capire i tipi di tutte le funzioni con le quali stai lavorando, cosa fanno e come le stai incollando.

+1

L'uso del dispositivo di rimozione della verruca sbt probabilmente catturerebbe quell'inferenza. –

+0

Intendi 'through io.stdOutLines', senza' tcp.lift'? Comunque non sembra che stia tirando fuori qualcosa dal flusso. –

+0

Ok: con 'tcp.lift' rimosso, funziona, ma si noti che è necessario' p.map (_. Run.run) .run.run' per eseguire i processi interni. –

Problemi correlati