functional-programming - 将 F# while-do "mutable"代码重构为功能性 "immutable"代码

标签 functional-programming f#

我一直在尝试将我的一个简单的 C# 控制台应用程序重新编写为纯函数式 F# 代码(如果可能的话)。到目前为止,我已经设法在 Seq(类似于 Seq.initInfinite sequenceGenerator |> Seq. takeWhile 条件 |> Seq.iter bodyOfWhileCycle) - “F# for Fun and Profit”网站一直是我的灵感来源。
然而,这次我遇到了一个简单的 while block ,它在“可变”F# 中看起来如下(并且有效):

printfn "Type low OP number"
let mutable lowLimit = parseMe (Console.ReadLine())                    
printfn "Type high OP number"
let mutable highLimit = parseMe (Console.ReadLine())                                            
let mutable myCondition = true
if highLimit > lowLimit then myCondition <- false            
while myCondition do 
      printfn "Type low OP number again"
      lowLimit <- parseMe (Console.ReadLine())                                  
      printfn "Type high OP number again"
      highLimit <- parseMe (Console.ReadLine())
      if highLimit > lowLimit then myCondition <- false

谁能帮我弄清楚如何将这个“可变”while-do block 重构为函数式样式?我重构它的尝试并没有奏效我想要 - 我不知道如何从 bodyOfWhileCycle 函数中获取 lowLimit1/highLimit1 值。我不成功的尝试之一在这里:

printfn "Type low OP number"
let lowLimit = parseMe (Console.ReadLine())                       
printfn "Type high OP number"
let highLimit = parseMe (Console.ReadLine())
let verifyingInputValues: unit = 
    let bodyOfWhileCycle _=    
                            printfn "Type low OP number again"
                            let lowLimit1 = parseMe (Console.ReadLine())                                  
                            printfn "Type high OP number again"
                            let highLimit1 = parseMe (Console.ReadLine())
                            ()                
    fun _ -> highLimit - lowLimit 
    |>  Seq.initInfinite 
    |>  Seq.takeWhile ((>) 0)
    |>  Seq.iter bodyOfWhileCycle   
verifyingInputValues

最佳答案

看起来您希望在 highLimit > lowLimit 时完成 while 循环,否则重复请求,并且可能稍后对它们执行某些操作。

在这种情况下,您需要一个返回 ( highLimit, lowLimit ) 而不是 unit () 元组的函数。通过将新状态作为参数传入,递归函数可以处理调用之间状态或 IO 的明显变化,没有可变性。

let fullParse: () -> int *int =
    let parseHighLow again = 
       printfn "Type low OP number %s" again
       let lowLimit = parseMe (Console.ReadLine())                                  
       printfn "Type high OP number %s" again
       let highLimit = parseMe (Console.ReadLine())
       highLimit, lowLimit
        
    let rec verify (high, low) = 
       if high > low  then high, low else verify (parseHighLow "again")
    verify (parseHighLow "")

let (high, low) = fullParse ()

关于functional-programming - 将 F# while-do "mutable"代码重构为功能性 "immutable"代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67045245/

相关文章:

F# ViewModel 未通过 XAML 中的 BindingContext 实例化

javascript - 可绑定(bind)和可调用模式的用途是什么?

scala - 如何在scala中默认使用不可变的Seq?

c# - c# 类上的 f# 模式匹配

c# - 如何从 F# 调用 Enumerable.Join?

f# - 模式匹配有多聪明?

f# - F# 中具有零复制语义的不安全强制转换

scala - 如何在抽象效果类型上配置猫计时器

scala - 过滤映射以获取无值

c - 我不小心用条件句(如果)更改了变量?