在FSI中,我想“轻松地”替换/模拟一个函数。这对于快速迭代非常有用,除非函数是泛型的,否则效果很好。例如:
// ... deep in some DLL
let int_op (x:int) = "hello "+(x.ToString())
let mutable realInt_op = int_op // OK!
let generic_op (x:'a) = "hello "+(x.ToString())
let mutable real_op = generic_op // Err: Value restriction!
// ... later in FSI
let mock_op x = "Waaaaasup "+(x.ToString())
do
real_op <- mock_op
那么,有没有一种“快速”模拟泛型函数的好方法呢?
发布于 2018-08-05 06:43:00
我可以看到三种可能性。就像Jwotsy提到的,如果你想这样做,你可以只做影子。
let intop (x:int) = "hello "+(x.ToString())
let mutable realIntop = intop
let inline genericop (x:'a) = "hello "+(x.ToString())
let realop = genericop
let mockop x = "Waaaaasup "+(x.ToString())
do
let realop = mockop
realop "" |> ignore //to make compile with partial example
这必须在一个表达式中,否则它不会工作:
let mockop x = "Waaaaasup "+(x.ToString())
let realop = mockop // Duplicate definition of value 'realop'
do ...
或者,由于您在这里与不变性作斗争,您可以切换到F#的面向对象功能:
let genericOp (x:'a) = sprintf "hello %A" x
type Container () =
member this.GenericOp<'a>(x:'a) = "hello generic " + (x.ToString())
member val intOp = genericOp with get,set
member val stringOp = genericOp with get,set
let c = new Container()
printfn "%s" (c.GenericOp "Test")
printfn "%s" (c.GenericOp 1)
printfn "%s" (c.stringOp "Test")
printfn "%s" (c.intOp 1)
let mockOp (x:'a) = sprintf "Mocked %A" x
do c.stringOp <- mockOp
do c.intOp <- mockOp
printfn "%s" (c.stringOp "Test")
printfn "%s" (c.intOp 1)
结果是:
hello generic Test
hello generic 1
hello "Test"
hello 1
Mocked "Test"
Mocked 1
最后,你可以改变你的方法,使用组合,这样你就可以感染你想模拟的函数,然后在注入的函数之间切换。类似于:
let generic_op (x:'a) = "hello "+(x.ToString())
let int_op (x:int) = "hello "+(x.ToString())
let realInt_op = int_op
let real_op = generic_op
let mock_op x = "Waaaaasup "+(x.ToString())
let doSomething f x =
do printfn "%s" (f x)
do doSomething realInt_op 1
do doSomething real_op "Real"
do doSomething mock_op "Mock"
https://stackoverflow.com/questions/51688329
复制相似问题