Parameters 如何存储方法并在以后向其提供多个参数
我试图跟踪值的使用情况,所以我将生成所述值的方法和输入(也被包装)包装到一个我称为Dataslot的类中。 我不知道我将预先包装什么方法和什么值,所以我尝试了各种方法来编写它,并认为下面的代码可以工作。 但是Parameters 如何存储方法并在以后向其提供多个参数,parameters,f#,Parameters,F#,我试图跟踪值的使用情况,所以我将生成所述值的方法和输入(也被包装)包装到一个我称为Dataslot的类中。 我不知道我将预先包装什么方法和什么值,所以我尝试了各种方法来编写它,并认为下面的代码可以工作。 但是let mutable value=funk unpack似乎不会导致funk-being被识别为一个函数,因此unpack方法似乎是错误的方法,我如何让它工作 type Dataslot(funk, input:Dataslot[]) as self = let mutable
let mutable value=funk unpack
似乎不会导致funk-being被识别为一个函数,因此unpack方法似乎是错误的方法,我如何让它工作
type Dataslot(funk, input:Dataslot[]) as self =
let mutable reffunk= funk
let refinput=input
let unpack= for inpu in refinput do inpu.Value
let mutable value = funk unpack
let uses= ResizeArray<Dataslot>[]
let get1()=
value
let mutable get0=fun()->get1()
let get2()=
value<-reffunk unpack
get0<-fun()->get1()
value
do for inpu in refinput do inpu.Subscribe(self)
member x.setfunk(fu)=
reffunk<-fu
for u in uses do
u.Changed
member x.setinput(index:int, inp:Dataslot)=
refinput.[index].Unsubscribe(self)
refinput.[index]=inp
refinput.[index].Subscribe(self)
for u in uses do
u.Changed
member x.Value
with get()=get0()
member x.Changed=get0<-fun()->get2()
member x.Subscribe(f)=
uses.Add(f) |>ignore
member x.Unsubscribe(f)=
uses.Remove(f) |>ignore
将Dataslot(funk,输入:Dataslot[])键入为self=
设可变reffunk=funk
设refinput=input
让unpack=在refinput do inpu.Value中输入
让可变值=funk解包
let uses=ResizeArray[]
让get1()=
价值
让可变的get0=fun()->get1()
让get2()=
价值忽略
我开始回答这个问题,但最后对示例的结构做了几处修改,因此它不再是一个直接的答案,而是另一种解决问题的方法,我认为您正在尝试解决这个问题。希望这仍然有帮助
我没有为Dataslot
使用一个具体的类,而是使用了一个接口,并且我还将接口设置为通用的,这样Dataslot)(a:Dataslot与
成员x.值=
如果handlers.Count>0,则值else f.value a.value
成员x.订阅h=
添加(h)
如果handlers.Count=1,则
fsub我开始回答这个问题,但最后我对你的例子的结构做了一些修改,所以这不再是一个直接的答案,而是另一种解决问题的方法,我想你正在尝试解决这个问题。希望这仍然会有帮助
我没有为Dataslot
使用一个具体的类,而是使用了一个接口,并且我还将接口设置为通用的,这样Dataslot)(a:Dataslot与
成员x.值=
如果handlers.Count>0,则值else f.value a.value
成员x.订阅h=
添加(h)
如果handlers.Count=1,则
fsub您可以将函数的签名保存在“内存”中,然后应用curry,直到最终得到返回您等待的值的真单参数函数为止,您可以将其保存在“内存”中函数的签名,然后,应用curry,直到你最终得到一个真正的单参数函数,返回你正在等待的值。它就像反应变量一样。传递给Subscribe
的函数可能是'T->unit
类型希望我理解这一点,你为externa添加了功能l方法订阅,但消除了只在调用函数值时才计算函数的延迟?@SvenHeinz是的,我认为订阅外部方法(就像函数一样)更通用,允许您创建重新计算的数据段链-但是现在我考虑到了这一点,我的代码可能有一个bug!当
中的处理程序数变为零时,它会停止重新计算(因为没有人在看),但当有人访问该值或有人再次开始侦听时,它应该重新计算。好的,我以前想知道是否发生了延迟更新,但最终找到了它,仍然担心性能,因为延迟值没有被记录,所以每次都会执行该函数。@SvenHeinz如果您不想订阅/取消订阅t这些都是循环中的事情,那么我认为保持缓存行为始终处于启用状态是非常明智的。我用这种(相当麻烦的)取消订阅行为编写了它,这样可以避免潜在的内存泄漏问题,但这些问题在您的用例中可能不会发生(所以“始终缓存”和“从不取消订阅”选项会简单得多,可能对您更有用!)这就像反应变量。可能传递给Subscribe的函数类型可能是'T->unit
Hmm希望我理解这一点,你为Subscribe添加了外部方法的功能,但消除了函数只有在调用其值时才进行计算的延迟?@SvenHeinz是的,我认为订阅外部方法s(就像函数一样)更通用,可以让您创建重新计算的数据段链-但现在我考虑到了这一点,我的代码可能有一个bug!当
中的处理程序数变为零时,它会停止重新计算(因为没有人在监视),但当有人访问该值或有人再次开始侦听时,它应该重新计算。好的,我以前想知道是否发生了延迟更新,但最终找到了它,仍然担心性能,因为延迟值没有被记录,所以每次都会执行该函数。@SvenHeinz如果您不想订阅/取消订阅t这些都是循环中的事情,那么我认为保持缓存行为始终处于启用状态是非常明智的。我用这种(相当麻烦的)取消订阅行为编写了它,这样可以避免潜在的内存泄漏问题,但这些问题在您的用例中可能不会发生(所以“始终缓存”和“从不取消订阅”选项会简单得多,可能对您更有用!)
type Dataslot<'T> =
abstract Value : 'T
abstract Subscribe : (unit -> unit) -> IDisposable
val mutableSlot : initial:'T -> ('T -> unit) * Dataslot<'T>
val immutableSlot : value:'T -> Dataslot<'T>
val ( <*> ) : f:Dataslot<('T -> 'R)> -> a:Dataslot<'T> -> Dataslot<'R>
let a = immutableSlot 10
let setB, b = mutableSlot 30
let res = immutableSlot (fun a b -> a + b) <*> a <*> b
let sub = res.Subscribe(fun () ->
printfn "Result changed to: %d" res.Value )
setB 32
setB 30
sub.Dispose()
setB 1
let mutableSlot initial =
let mutable value = initial
let handlers = ResizeArray<_>()
(fun newValue ->
value <- newValue
for h in handlers do h()),
{ new Dataslot<'T> with
member x.Value = value
member x.Subscribe h =
handlers.Add(h)
{ new IDisposable with
member x.Dispose() = handlers.Remove(h) |> ignore } }
let immutableSlot value =
{ new Dataslot<'T> with
member x.Value = value
member x.Subscribe _ =
{ new IDisposable with member x.Dispose () = () } }
let (<*>) (f:Dataslot<'T -> 'R>) (a:Dataslot<'T>) =
let mutable value = f.Value a.Value
let handlers = ResizeArray<_>()
let update () =
value <- f.Value a.Value
for h in handlers do h()
let mutable fsub = { new IDisposable with member x.Dispose() = () }
let mutable asub = { new IDisposable with member x.Dispose() = () }
{ new Dataslot<'R> with
member x.Value =
if handlers.Count > 0 then value else f.Value a.Value
member x.Subscribe h =
handlers.Add(h)
if handlers.Count = 1 then
fsub <- f.Subscribe(update)
asub <- a.Subscribe(update)
value <- f.Value a.Value
{ new IDisposable with
member x.Dispose() =
handlers.Remove(h) |> ignore
if handlers.Count = 0 then
fsub.Dispose()
asub.Dispose() } }