F # как удалить переменные в функции - PullRequest
0 голосов
/ 01 марта 2019

Я выполняю рефакторинг программы на F #, пытаясь сделать это на 100% без ключевого слова mutable, но у меня есть проблема в этой функции:

  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, он получит значение как константуЯ знаю, что это нечистая функция, меня интересует, как правильно реорганизовать функцию и как изменить ее, чтобы сделать ее функциональной настолько чистой, насколько это возможно, и удалить слово изменяемое, но сохранить поведение.Спасибо

1 Ответ

0 голосов
/ 02 марта 2019

Вы можете преобразовать цикл 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
...