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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.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
F#-当给定元组条件时_F# - Fatal编程技术网

F#-当给定元组条件时

F#-当给定元组条件时,f#,F#,鉴于以下情况: #light //any function returning bool * 'a let foo = let x = ref 10 fun () -> x := !x - 1 if !x <> 0 then (true, x) else (false, x) while let (c,x) = foo() in c do print_any x;/

鉴于以下情况:

#light
//any function returning bool * 'a
let foo =
    let x = ref 10
    fun () ->
        x := !x - 1
        if !x <> 0 then
            (true, x)
        else
            (false, x)

while let (c,x) = foo() in c do print_any x;//can't access x, but would be convinent.

//this is how I want it to work, without all the typing
let rec loop f =
    match f() with
    | (true, x) ->
        print_any x
        loop f
    | (false, _) -> ()
loop foo
#灯
//任何返回bool*'a的函数
让福=
设x=ref 10
乐趣()->
x:=!x-1
如果!那么x0
(对,x)
其他的
(假,x)
而让c中的(c,x)=foo()打印任意x//无法访问x,但会很方便。
//这就是我想要的工作方式,不需要所有的打字
让rec循环f=
将f()与
|(对,x)->
打印任意x
回路f
|(假)->(假)
环福
我该如何着手解决这个问题?
或者我应该把“foo”转换成序列表达式吗?

这是一种解决方案,但我个人认为这是while构造的滥用

#light
while 
   (let (c,x) = foo()
    if c then print_any !x
    c)
   do ()

另一个在我看来稍微好一点的解决方案。它从while的condition子句范围中获取x,并将其放入引用y中,该引用y在更高的范围中可用。仍然不是最好的(功能性)解决方案,但它可以工作

let y = ref 1
while (let (c,x) = foo()
       y := !x
       c)
       do printf "%i" !y
我认为您的
rec循环
解决方案效果最好,因为它是功能最强大的解决方案(避免副作用,尽管foo使用state)和最通用的解决方案(它与foo同时作用于所有功能)。它的输入时间更长,但如果您使用更多像foo这样的函数,则循环比只针对foo的单个最短解决方案更高效

我甚至会进一步概括循环,并抽象出在“真实”情况下您希望对值执行的操作:

let loop f a = 
   let rec loop2() = 
      match f() with
      | (true, x) ->
         a x
         loop2()
      | (false, _) -> ()
   loop2()

loop foo print_any

我喜欢关于如何消费“foo”的其他建议,假设foo是固定的

在我的鼻子里,“foo”的代码有味道。如果将“foo”转换为“bar”是合理的

let bar =    
    let x = ref 10    
    seq {
        x := !x - 1        
        while !x <> 0 do
            yield x
            x := !x - 1        
    }
bar |> Seq.iter print_any
let bar=
设x=ref 10
序号{
x:=!x-1
同时!x0做什么
产量x
x:=!x-1
}
bar |>Seq.iter print|u any
然后我会这样做,但“酒吧”,虽然稍微好一点,仍然显得可疑。(在“bar”中,我保留了一个奇怪的方面,即它返回“intref”,而不是像“foo”那样只返回“int”,但希望这个方面是无意的?)


我认为关于“foo”的有趣之处在于数据类型中不明显的隐式信息(只要bool部分为真,您可以继续调用它),这使得seq版本更具吸引力。

您能描述一下您试图解决的问题,而不是引用一个不起作用的解决方案吗?