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
Syntax while循环在F#的计算表达式中扮演什么角色?_Syntax_F#_Computation Expression - Fatal编程技术网

Syntax while循环在F#的计算表达式中扮演什么角色?

Syntax while循环在F#的计算表达式中扮演什么角色?,syntax,f#,computation-expression,Syntax,F#,Computation Expression,如果定义生成器对象的While方法,则可以在中使用While-循环。While方法的签名为: member b.While (predicate:unit->bool, body:M<'a>) : M<'a> member b.For (items:seq<'a>, body:unit->M<'a>) : M<'a> 您应该注意到,在While-方法中,主体是一个简单类型,而不是For方法中的函数 您可以在计算表达式中嵌

如果定义生成器对象的
While
方法,则可以在中使用
While
-循环。
While
方法的签名为:

member b.While (predicate:unit->bool, body:M<'a>) : M<'a>
member b.For (items:seq<'a>, body:unit->M<'a>) : M<'a>
您应该注意到,在
While
-方法中,主体是一个简单类型,而不是
For
方法中的函数

您可以在计算表达式中嵌入一些其他语句,如
let
和函数调用,但这些语句不可能在
while
-循环中执行多次

builder {
    while foo() do
      printfn "step"
      yield bar()
}
为什么
while
循环不执行多次,而只是重复执行?为什么与for循环有显著差异?更好的是,在计算表达式中使用while循环是否有一些预定的策略?

如果您查看,您将看到这一点

while foo() do
  printfn "step"
  yield bar()
翻译成

builder.While(fun () -> foo(), 
              builder.Delay(fun () -> 
                              printfn "step"
                              builder.Yield(bar()))))
这种转换允许多次计算while循环的主体。虽然您的类型签名对于某些计算表达式(例如
seq
async
)是准确的,但请注意,插入对
Delay
的调用可能会导致不同的签名。例如,您可以这样定义列表生成器:

type ListBuilder() =
  member x.Delay f = f
  member x.While(f, l) = if f() then l() @ (x.While(f, l)) else []
  member x.Yield(i) = [i]
  member x.Combine(l1,l2) = l1 @ l2()
  member x.Zero() = []
  member x.Run f = f()

let list = ListBuilder()
现在,您可以计算表达式,如:

list {
  let x = ref 0
  while !x < 10 do
    yield !x
    x := !x + 1
}
列表{
设x=ref 0
而!x<10 do
屈服
x:=!x+1
}
获取与
[0..9]
等价的值


在这里,我们的
While
方法的签名是
(unit->bool)*(unit->'a list)->'a list
,而不是
(unit->bool)*'a list->'a list
。一般来说,当
延迟
操作的类型为
(unit->M>
时,
While
方法的签名将是
(unit->bool)*D

很好。我不知道
运行