r(IO.succeed(SingleValue(p.a + p.b))) case r@Sub(p) => r(IO.succeed(SingleValue(p.a - p.b))) case r@Mul(p) => r(IO.succeed(SingleValue(p.a * p.b))) case r@Div(p) => r(IO.succeed(SingleValue(p.a / p.b))) case r@Neg(p) => r(IO.succeed(SingleValue(-p.a))) } val streaming: StreamingFunction[GrpcIO, GrpcStream] = { case r@RequestStream(p) => r(fromIterable(Iterator.fill(p.a.toInt)(SingleValue(42)).toIterable)) case r@ConsumeStream(s) => r(s.map(_.a.toInt).foldLeft(0)(_+_).map(SingleValue(_))) case r@BiStream(s) => r(s) } type GrpcIO[T] = IO[StatusRuntimeException, T] type GrpcStream[T] = Stream[StatusRuntimeException, T] FUNCTION