如何在scalaz流中实现接收可用传感器 简短版本:

如何在scalaz流中实现接收可用传感器 简短版本:,scala,scalaz-stream,Scala,Scalaz Stream,我想实现一个函数,返回一个等待一个值块被“发射”的转换器 我心目中的功能将具有以下签名: /** * The `Process1` which awaits the next "effect" to occur and passes all values emitted by * this effect to `rcv` to determine the next state. */ def receiveBlock[I, O](rcv: Vector[I] => Process1[

我想实现一个函数,返回一个等待一个值块被“发射”的转换器

我心目中的功能将具有以下签名:

/**
 * The `Process1` which awaits the next "effect" to occur and passes all values emitted by
 * this effect to `rcv` to determine the next state.
 */
def receiveBlock[I, O](rcv: Vector[I] => Process1[I,O]): Process1[I,O] = ???
细节: 我的理解是,我可以使用此函数来实现以下我认为非常有用的函数:

/**
  * Groups inputs into chunks of dynamic size based on the various effects
  * that back emitted values.
  *
  * @example {{{
  * val numberTask = Task.delay(1)
  * val listOfNumbersTask = Task.delay(List(5,6,7))
  * val sample = Process.eval(numberTask) ++ Process(2,3,4) ++ Process.await(listOfNumbersTask)(xs => Process.emitAll(xs))
  * sample.chunkByEffect.runLog.run should be List(Vector(1), Vector(2,3,4), Vector(5,6,7))
  * }}}
  */
  def chunkByEffect[I]: Process1[I, Vector[I]] = {
    receiveBlock(vec => emit(vec) ++ chunkByEffect)
  }
[更新]更多详细信息 我的最终目标(稍微简化)是实现以下功能:

/**
 * Transforms a stream of audio into a stream of text.
 */
voiceRecognition(audio: Process[Task, Byte]): Process[Task, String]
该功能可对语音识别服务进行外部调用。因此,对流中的每个
字节进行网络调用是不合理的。在进行网络呼叫之前,我需要将字节组合在一起。我可以将
audio
制作成
进程[Task,ByteVector]
,但这需要测试代码才能知道函数支持的最大块大小,我宁愿由函数本身来管理。此外,当此服务在服务内部使用时,该服务本身将接收具有给定大小音频的网络呼叫,我希望
chunkXXX
函数在分块方面是智能的,这样它就不会保留已经可用的数据


基本上,来自网络的音频流的形式为
Process[Task,ByteVector]
,并通过
flatMap(Process.emitAll())将其转换为
Process[Task,Byte]
。但是,测试代码将直接生成一个
进程[任务,字节]
,并将其输入到
语音识别中。从理论上讲,我相信如果提供适当的组合器,就有可能提供一个
语音识别
的实现,该实现对这两个流都做了正确的事情,我认为上面描述的
chunkByEffect
功能是实现这一点的关键。我现在意识到,我需要chunkByEffect函数具有
min
max
参数,该参数指定分块的最小和最大大小,而不考虑产生字节的底层
任务。

您需要以某种方式将字节分开。我建议在字节流上使用更高级别的抽象,即字节向量

然后您可能需要手动执行process1,它的实现类似于
process1.chunkBy
,只对字节向量进行操作。i、 e

def chunkBy(separator:ByteVector): Process1[ByteVector, ByteVector] = {
  def go(acc: ByteVector): Process1[ByteVector, ByteVector] =
    receive1Or[ByteVector,ByteVector](emit(acc)) { i =>
       // implement searching of separator in accumulated + new bytes
       ???
    }
  go(ByteVector.empty)
}
然后这会把所有的东西连接起来

val speech: Process[Task,ByteVector] = ???
def chunkByWhatever: Process1[ByteVector,ByteVector] = ??? 
val recognizer: Channel[Task,ByteVector,String] = ???

//this shall do the trick
speech.pipe(chunkByWhatever).through(recognizer)

我想这一点的答案是,在
scalaz-stream
property中很难或不可能做到这一点。这个库的新版本名为
fs2
,它对“分块”有一流的支持,这正是我在这里寻找的。除非我遗漏了什么,否则它们的行为都不像我上面描述的
chunkByEffect
。也许我没有很好地描述我希望完成的事情。一旦我可以访问桌面,我会编辑这个问题。效果到底是什么?像任务评估?是的,任务评估就是我所说的效果。