F#如何删除函数中的变量

时间:2019-03-01 20:50:58

标签: .net functional-programming f#

我正在重构F#中的程序,试图在不使用关键字mutable的情况下100%完成该程序,但是此功能存在问题:

  let ReadAndProcessCardData() = 
      let mutable pasobyte = serialPort1.BytesToRead
      let mutable pasobyte2 = 0

      while (pasobyte <> pasobyte2) 
            do
              pasobyte <- serialPort1.BytesToRead
              Thread.Sleep(2);
              pasobyte2 <- serialPort1.BytesToRead

      let mutable arr = [| for i in 1..serialPort1.BytesToRead -> byte(i*i)|]
      serialPort1.Read( arr , 0 , arr.Length ) |>ignore
      ByteArrayToString(arr) |> printCardGuid

我正在尝试等待几毫秒,然后检查到达串行端口的流是否已结束,或者仍然有更多数据进入,但是如果我编译了函数,则BytesToRead属性会在我读取它之前更改作为递归而不是while循环,它获取的值是一个常量,我知道这是一个不纯函数,我想知道什么是重构函数的正确方法,以及如何对其进行更改以使其成为100的纯函数尽可能删除“可变”一词,但保持其行为。 谢谢

1 个答案:

答案 0 :(得分:1)

您可以将while循环转换为递归函数,而无需做很多工作。此外,最好将串行端口作为参数传递。然后,该函数将大致如下所示:

let readAndProcessCardData (sp : System.IO.Ports.SerialPort) =
    let rec waitLoop b1 b2 =
        if b1 = b2 then b1 else
            let bb1 = sp.BytesToRead
            Thread.Sleep 2
            let bb2 = sp.BytesToRead
            waitLoop bb1 bb2
    let readLen = waitLoop 0 1
    let arr = Array.zeroCreate readLen
    sp.Read (arr, 0, arr.Length) |> ignore
    byteArrayToString arr |> printCardGuid