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



我一直在尝试将我的一个简单的C#控制台应用程序重写为纯功能的F#代码(如果可能的话(。到目前为止,我已经设法将块重写为";不可变的";F#在Seq的帮助下(类似于Seq.initInfinite sequenceGenerator|>Seq.takeWhile condition|>Seq.iter bodyOfWhileCycle(-网站";F#的乐趣和利润";一直是我的灵感来源
然而,这一次我遇到了一个简单的在";可变的";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

有人能帮我弄清楚如何重构这个"可变的">是否阻塞为函数样式我重构它的尝试没有按我想要的方式进行——我不知道如何从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时完成while循环>lowLimit和以其他方式重复请求,并可能稍后对它们做些什么。

在这种情况下,您需要一个返回元组(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 ()

注意skip而不是take,因为我们正在等待从用户那里收到我们想要的内容。我们想要的是一件事,所以我们将head函数应用于序列。总的来说,你的尝试很接近,但你的顺序没有产生价值。

open System
let rec p name = 
printfn "Input %s Value" name
let text = Console.ReadLine()
let (ok, i) = Int32.TryParse text
if ok then i else p name

let ps () = 
Seq.initInfinite (fun _ -> p "High", p "Low")
|> Seq.skipWhile (fun (high, low) -> high <= low)
|> Seq.head
let (high, low) = ps ()

相关内容

  • 没有找到相关文章

最新更新