我试图在F#中测试一个MailboxProcessor.我想测试我发布的函数f实际上是在发布消息时执行的.
原始代码使用的是Xunit,但我创建了一个fsx,我可以使用fsharpi执行它.
到目前为止我这样做:
open System
open FSharp
open System.Threading
open System.Threading.Tasks
module MyModule =
type Agent<'a> = MailboxProcessor<'a>
let waitingFor timeOut (v:'a)=
let cts = new CancellationTokenSource(timeOut|> int)
let tcs = new TaskCompletionSource<'a>()
cts.Token.Register(fun (_) -> tcs.SetCanceled()) |> ignore
tcs ,Async.AwaitTask tcs.Task
type MyProcessor<'a>(f:'a->unit) =
let agent = Agent<'a>.Start(fun inbox ->
let rec loop() = async {
let! msg = inbox.Receive()
// some more complex should be used here
f msg
return! loop()
}
loop()
)
member this.Post(msg:'a) =
agent.Post …Run Code Online (Sandbox Code Playgroud) 我定义了不同的类型:
type TypeNull() = class end
type MyType1 = {
a:int;
b:int
}
type MyType2 = {
a:string;
b:int
}
type MyType3 = {
a:string;
b:DateTime
}
Run Code Online (Sandbox Code Playgroud)
和使用它们的不同的歧视联盟:
type myDU =
| A of int
| B of string
| C of string
type myDU2 =
| D of MyType1
| E of MyType2
| F of TypeNull
Run Code Online (Sandbox Code Playgroud)
我有功能将myDU映射到myDU2:
let applyArray = function
| A x -> [E({a="1"; b=2})]
| B x -> [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
| C x …Run Code Online (Sandbox Code Playgroud) 我有一个值序列,我想部分地应用于函数:
let f a b c d e= a+b+c+d+e
let items = [1,2,3,4,5]
let result = applyPartially f items
Assert.Equal(15, result)
Run Code Online (Sandbox Code Playgroud)
我正在寻找applyPartially函数.我试过写这样的递归函数:
let rec applyPartially f items =
| [] -> f
| [x] -> f x
| head :: tail -> applyPartially (f head) tail
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是f类型在我的迭代开始'a - >'b - >'c - >'d - >'e,并且对于每个循环它应该消耗一个订单.
'a->'b->'c->'d->'e
'b->'c->'d->'e
'c->'d->'e
'd->'e
Run Code Online (Sandbox Code Playgroud)
这意味着我能想到的下界面将是'd - >'e.我怎么能隐藏我的函数的复杂性,以便在递归函数中只显示'd - >'e?