В общем, вы должны стараться использовать неизменяемые типы данных и избегать императивных конструкций, таких как глобальные переменные и императивные циклы - хотя во многих случаях их использование в F # хорошо, их следует использовать только тогда, когда для этого есть веская причина , Вот пара примеров, где вы можете использовать функциональный подход:
Прежде всего, чтобы сделать код более функциональным, вам следует избегать использования глобального изменяемого кэша. Вместо этого ваша функция RefreshCache
должна возвращать данные в качестве результата (предпочтительно с использованием некоторой функциональной структуры данных, такой как тип F # Map
):
let PopulateCache quoteList =
quoteList
// Generate a sequence of tuples containing key and value
|> Seq.map (fun result -> result.RicCode, result)
// Turn the sequence into an F# immutable map (replacement for hashtable)
|> Map.ofSeq
Код, который его использует, будет изменен следующим образом:
let cache =
sr.ReadLine()
|> ParseQuoteString
|> PopulateCache
printfn "[F#]Quot Size, %d" m_cache.Count
let quot = m_cache.["MSFT.OQ"]
// The rest of the sample stays the same
В функции EstablishConnection
вам определенно не нужно объявлять непостоянную переменную sr
, потому что в случае исключения функция вернет null
. Вместо этого я бы использовал тип option
, чтобы убедиться, что этот случай обрабатывается:
let EstablishConnection() =
let pipeServer =
new NamedPipeServerStream("testpipe", PipeDirection.InOut, 4)
printfn "[F#] NamedPipeServerStream thread created..."
pipeServer.WaitForConnection()
printfn "[F#] Client connected."
try // Wrap the result in 'Some' to denote success
Some(new StreamReader(pipeServer))
with e ->
printfn "[F#]ERROR: %s" e.Message
// Return 'None' to denote a failure
None
Основной цикл может быть записан с использованием рекурсивной функции, которая останавливается при сбое EstablishConnection
:
let rec loop() =
match EstablishConnection() with
| Some(conn) ->
printfn "[F#] Ready to Receive data"
// rest of the code
loop() // continue looping
| _ -> () // Quit