F# 使用构造函数作为函数
F# use constructors as functions
我有一个将派生类型的构造函数视为委托的用例,但我不知道这是不可能的还是我无法解决。
type SomeJobEvent(jobId : int, otherThing : string) =
member this.JobId = jobId
member this.OtherThing = otherThing
type SomeJobStarted(jobId : int, otherThing : string) =
inherit SomeJobEvent(jobId, otherThing)
type SomeJobComplete(jobId : int, otherThing : string) =
inherit SomeJobEvent(jobId, otherThing)
type SomeJobError(jobId : int, otherThing : string) =
inherit SomeJobEvent(jobId, otherThing)
让我们想象一下,这就是模型,在现实生活中,模型恰好是用 C# 编写的,而我的代码是用 F# 编写的,但为了简洁起见,在 F# 中输入要容易得多。
而我想做的是...
let raise eventObject =
// This is just a helper, the raise event takes obj.
eventRaiser.Raise(eventObject)
let raise jobId otherThing eventConstructor =
// Lets treat the 'event' constructor as a function
raise(eventConstructor(jobId, otherThing))
[<EntryPoint>]
let main args =
// Lets curry this function up so I don't have to pass around 1234
let raiseEventForJob1234 = raise 1234 "other thing"
raiseEventForJob1234 SomeJobStarted
raiseEventForJob1234 SomeJobComplete
现在,由于传递给 raiseEventForJob1234
的构造函数具有相同的签名并且是同一继承链的一部分,因此感觉是可行的。就是不知道怎么弄,还不是都嘎嘎叫,其实都是鸭子!
编辑:这里有来自 @tomas, but also a really useful extension from 的一个很好的答案,请务必检查两者。
您遇到的问题称为值限制 - 基本上,如果您想将函数用作泛型,则必须将其定义为显式函数。
在你的例子中 raiseEventForJob1234
是通用的(它可以创建和触发不同类型的事件),但它被定义为一个值。添加一个参数可以解决这个问题:
let raiseEventForJob1234 f = raise 1234 "other thing" f
raiseEventForJob1234 SomeJobStarted
raiseEventForJob1234 SomeJobComplete
另请注意,这仅适用于 F# 4.0(Visual Studio 2015)。以前版本的 F# 不支持将构造函数视为函数。
我有一个将派生类型的构造函数视为委托的用例,但我不知道这是不可能的还是我无法解决。
type SomeJobEvent(jobId : int, otherThing : string) =
member this.JobId = jobId
member this.OtherThing = otherThing
type SomeJobStarted(jobId : int, otherThing : string) =
inherit SomeJobEvent(jobId, otherThing)
type SomeJobComplete(jobId : int, otherThing : string) =
inherit SomeJobEvent(jobId, otherThing)
type SomeJobError(jobId : int, otherThing : string) =
inherit SomeJobEvent(jobId, otherThing)
让我们想象一下,这就是模型,在现实生活中,模型恰好是用 C# 编写的,而我的代码是用 F# 编写的,但为了简洁起见,在 F# 中输入要容易得多。
而我想做的是...
let raise eventObject =
// This is just a helper, the raise event takes obj.
eventRaiser.Raise(eventObject)
let raise jobId otherThing eventConstructor =
// Lets treat the 'event' constructor as a function
raise(eventConstructor(jobId, otherThing))
[<EntryPoint>]
let main args =
// Lets curry this function up so I don't have to pass around 1234
let raiseEventForJob1234 = raise 1234 "other thing"
raiseEventForJob1234 SomeJobStarted
raiseEventForJob1234 SomeJobComplete
现在,由于传递给 raiseEventForJob1234
的构造函数具有相同的签名并且是同一继承链的一部分,因此感觉是可行的。就是不知道怎么弄,还不是都嘎嘎叫,其实都是鸭子!
编辑:这里有来自 @tomas, but also a really useful extension from
您遇到的问题称为值限制 - 基本上,如果您想将函数用作泛型,则必须将其定义为显式函数。
在你的例子中 raiseEventForJob1234
是通用的(它可以创建和触发不同类型的事件),但它被定义为一个值。添加一个参数可以解决这个问题:
let raiseEventForJob1234 f = raise 1234 "other thing" f
raiseEventForJob1234 SomeJobStarted
raiseEventForJob1234 SomeJobComplete
另请注意,这仅适用于 F# 4.0(Visual Studio 2015)。以前版本的 F# 不支持将构造函数视为函数。