【问题标题】:F# how remove variables in functionF#如何删除函数中的变量
【发布时间】:2019-07-23 22:16:50
【问题描述】:

我正在用 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个纯函数尽可能并删除单词 mutable 但保持行为。 谢谢

【问题讨论】:

  • 你能证明你尝试使函数递归并解释它有什么问题吗?

标签: .net functional-programming f#


【解决方案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

【讨论】:

  • 我只需要更改 let arr = Array.zeroCreate readLen 这一行
  • 对于这个:让 arr = [|对于 i in 1..serialPort1.BytesToRead -> byte(i*i)|]
猜你喜欢
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
  • 2018-05-22
  • 2023-03-22
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 2011-10-12
相关资源
最近更新 更多