簡體   English   中英

當使用scalaz-stream中的“ halt”時,“ wye”組合器的副作用

[英]side-effects for `wye` combinators when using `halt` from scalaz-stream

filter (內部使用halt )終止其他分支,即使它有一些副作用:

scala> val p = Process("1","2", "3")
scala> val p1 = p.filter(_ => true).map(_ + "p1").observe(io.stdOutLines)
scala> val p2 = p.filter(_ => false).map(_ + "p2").observe(io.stdOutLines)
scala> (p1 yip p2).run.run
1p1

scala> val p2 = p.filter(_ => true).map(_ + "p1").observe(io.stdOutLines)
scala> (p1 yip p2).run.run
1p1
1p2
2p1
2p2
3p1
3p2

似乎合乎邏輯,因為在該filter之后沒有值要返回到yip 但是observe的副作用呢?

我當前的解決方案是使用flatMap指定默認值:

scala> val p1 = p.map(_ + "p1").flatMap(x => Process.emit(x).observe(io.stdOutLines))

scala> val p2 = p.map(_ + "p2").flatMap(x => Process.emit(""))

scala> (p1 yip p2).run.run
1p1
2p1
3p1

但是也許有一種使用filter嗎?

PS merge組合器為其他分支執行副作用(因為它不需要返回值),但是如果一個分支暫停,它就不會等待其他分支(即使它具有副作用)。

即使在p2終止后也要運行效果,需要明確的default行為。 因此,可能有以下解決方案:

  1. 定義p2以在終止后提供默認值
  2. 如果我們真的不需要元組,請使用either來獲得權利

也許(1)更接近問題,代碼看起來像:

val p = Process("1","2", "3")
val p1 = p.filter(_ => true).map(_ + "p1").observe(io.stdOutLines)
val p2 = p.filter(_ => false).map(_ + "p2")
         .observe(io.stdOutLines).map(Some(_)) ++ emit(None).repeat
// alternativelly
// val p2 = p.map { v =>  if (pred(v)) right(v) else left(v) }
//          .observeO(o.stdOutLines).flatMap { _.toOption }
//          ++ emit(None).repeat             

(p1 yip p2).run.run

實際上,應該是這樣的:

in.map(emit).flatMap{ p =>
  val p1 = p.map(_ + "p1").filter(_ => true).observe(out)
  val p2 = p.map(_ + "p2").filter(_ => false).observe(out)
  p1 merge p2
}.run.run

它使所有副作用都井井有條,因為filter不能獲得一個以上的值(由發出產生)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM