2014-07-16 163 views
6

我試圖寫入以下功能停止在用戶輸入

def haltOnUserInput[O](process: Process[Task, O]): Process[Task, O] 

在用戶發送上stdin一行其停止process一個Process [任務,O]。在這種情況下,可以在結束進程本身之前等待進程中的當前計算結束。

我曾嘗試以下:

scala> :paste 
// Entering paste mode (ctrl-D to finish) 

import scalaz.{ -\/, \/-, \/ } 
import scalaz.stream._ 
import scalaz.concurrent.Task 

def haltOnUserInput[O](process: Process[Task, O]): Process[Task, O] = { 
    process.either(io.stdInLines).flatMap { 
    case -\/(o) => Process.emit(o) 
    case \/-(_) => println("here"); Process.halt 
    } 
} 

而且我測試這樣的:

scala> val oneSec = scala.concurrent.duration.Duration("1s") 
oneSec: scala.concurrent.duration.Duration = 1 second 

scala> val test = haltOnUserInput(Process.awakeEvery(oneSec)).take(10).map(_.toString).to(io.stdOutLines).run 
test: scalaz.concurrent.Task[Unit] = [email protected] 

scala> test.run 
1000144294 nanoseconds 
2000148316 nanoseconds 
here 
3000130736 nanoseconds 
here 
4000124898 nanoseconds 
5000189134 nanoseconds 
6000201269 nanoseconds 
here 
7000127797 nanoseconds 
8000132194 nanoseconds 
9000191001 nanoseconds 
10000126974 nanoseconds 

正如你所看到的,用戶的輸入被確認(「這裏」被打印出來,好幾次)但過程不會中斷。我不確定flatMap的行爲如預期那樣Process.halt

任何關於如何正確書寫haltOnUserInput

+0

什麼 – Daenyth

+0

@Daenyth我已經作出了明確的問題,這裏實際的問題:如何正確寫入'haltOnUserInput'? – betehess

回答

4

另一種解決方案是使用wye.interrupt:

val input = io.stdInLines.take(1).map(_ => true) 
val dory = Process.awakeEvery(1.second).map(_ => println("Hi!")) 
val process = input.wye(dory)(wye.interrupt) 
process.run.run 
+0

很好!順便說一下,'.take(1)'在這裏沒用。 – betehess

+0

這個答案幫助了我,謝謝。可能需要此更改:http://stackoverflow.com/questions/32852039/why-awakeevery-was-removed-from-scalaz-stream –

1

這是我實現haltOnUserInput的:

def haltOnUserInput[O](process: Process[Task, O]): Process[Task, O] = { 
    val stop = Process.constant(()) either io.stdInLines map (_.isRight) 
    process.until(stop) 
    }