Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parameters 如何存储方法并在以后向其提供多个参数_Parameters_F# - Fatal编程技术网

Parameters 如何存储方法并在以后向其提供多个参数

Parameters 如何存储方法并在以后向其提供多个参数,parameters,f#,Parameters,F#,我试图跟踪值的使用情况,所以我将生成所述值的方法和输入(也被包装)包装到一个我称为Dataslot的类中。 我不知道我将预先包装什么方法和什么值,所以我尝试了各种方法来编写它,并认为下面的代码可以工作。 但是let mutable value=funk unpack似乎不会导致funk-being被识别为一个函数,因此unpack方法似乎是错误的方法,我如何让它工作 type Dataslot(funk, input:Dataslot[]) as self = let mutable

我试图跟踪值的使用情况,所以我将生成所述值的方法和输入(也被包装)包装到一个我称为Dataslot的类中。 我不知道我将预先包装什么方法和什么值,所以我尝试了各种方法来编写它,并认为下面的代码可以工作。 但是
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() } }