gpt4 book ai didi

scala - 为什么这样的操作符定义在 Scala 中是可能的?

转载 作者:行者123 更新时间:2023-12-03 23:27:50 25 4
gpt4 key购买 nike

我使用 F# 并且不太了解 Scala,只是这些语言之间通常有一些相似之处。但是在查看 Scala 中的 Akka Streams 实现时,我注意到运算符 ~> 的使用方式在 F# 中是不可能的(不幸的是)。我不是在谈论只能在 F# 中一元运算符开头使用的符号“~”,这并不重要。让我印象深刻的是可以像这样定义图形:

in ~> f1 ~> bcast ~> f2 ~> merge ~> f3 ~> out
bcast ~> f4 ~> merge

由于各种图形元素具有不同的类型(Source、Flow、Sink),因此不可能在 F# 中定义一个可以跨它们工作的运算符。但我想知道为什么这在 Scala 中是可能的——这是因为 Scala 支持方法函数重载(而 F# 不支持)?

更新。 Fydor Soikin 展示了几种在 F# 中重载的方法,可用于在使用 F# 时实现类似的语法。我试过这个,这里它看起来如何:

type StreamSource<'a,'b,'c,'d>(source: Source<'a,'b>) = 
member this.connect(flow : Flow<'a,'c,'d>) = source.Via(flow)
member this.connect(sink: Sink<'a, Task>) = source.To(sink)

type StreamFlow<'a,'b,'c>(flow : Flow<'a,'b,'c>) =
member this.connect(sink: Sink<'b, Task>) = flow.To(sink)

type StreamOp = StreamOp with
static member inline ($) (StreamOp, source: Source<'a,'b>) = StreamSource source
static member inline ($) (StreamOp, flow : Flow<'a,'b,'c>) = StreamFlow flow

let inline connect (a: ^a) (b: ^b) = (^a : (member connect: ^b -> ^c) (a, b))
let inline (>~>) (a: ^a) (b: ^b) = connect (StreamOp $ a) b

现在我们可以编写如下代码:
let nums = seq { 11..13 }
let source = nums |> Source.From
let sink = Sink.ForEach(fun x -> printfn "%d" x)
let flow = Flow.FromFunction(fun x -> x * 2)
let runnable = source >~> flow >~> sink

最佳答案

实际上,Scala 至少有四种不同的方式使其工作。

(1) 方法重载。

def ~>(f: Flow) = ???
def ~>(s: Sink) = ???

(2) 继承。
trait Streamable { 
def ~>(s: Streamable) = ???
}
class Flow extends Streamable { ... }
class Sink extends Streamable { ... }

(3) 类型类和类似的泛型结构。
def ~>[A: Streamable](a: A) = ???

(带有提供所需功能的 Streamable[Flow], Streamable[Sink], ... 实例)。

(4) 隐式转换。
def ~>(s: Streamable) = ???

(与 implicit def flowCanStream(f: Flow): Streamable = ??? 等)。

每一种都有自己的优点和缺点,并且都在各种库中大量使用,尽管最后一种由于太容易产生惊喜而有些失宠。但是要获得您所描述的行为,其中任何一个都可以。

实际上,在 Akka Streams 中,据我所知,它实际上是 1-3 的混合。

关于scala - 为什么这样的操作符定义在 Scala 中是可能的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40050842/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com