Usage style binding for a one-time object returned as an option

I wonder if there is an elegant way to do the following:

I have a function that creates a one-time and returns it as an option. The caller is called. Now, since the wrapped object is bound inside the match case, I don’t know how to bind the “use” style inside the match so that the object fits correctly.

let createSocket (hostEntry:IPHostEntry) = let httpPort = 80 let endpoint = new IPEndPoint(hostEntry.AddressList.[0], httpPort) let socket = new Socket(endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp) socket.Connect(endpoint) if (socket.Connected) then Some socket else None let fetchResource url = let uri = new System.Uri(url) let hostEntry = Dns.GetHostEntry(uri.Host) match createSocket(hostEntry) with | Some socket -> use s = socket // More elegant way? sendRequest s uri.Host uri.PathAndQuery |> getResponse | None -> "Failed to open socket" 
+6
source share
3 answers

You have a using function available in the main library, but it is up to you whether you think this is more elegant:

 match createSocket(hostEntry) with | Some socket -> using socket <| fun s -> sendRequest s uri.Host uri.PathAndQuery |> getResponse | None -> "Failed to open socket" 

You can do it even further and pack the whole trick into one function:

 module Option = let using func = Option.bind (fun disp -> using disp func) ... createSocket(hostEntry) |> Option.using (fun s -> sendRequest s uri.Host uri.PathAndQuery |> getResponse) // handle None however you like |> function Some x -> x | None -> "Failed to open socket" 

Although I do not remember that I ever felt the need to do it personally.

+4
source

I think null is the most elegant here.

 if socket.Connected then socket else null ... use s = createSocket(hostEntry) if s = null then "Failed..." else sendRequest... 

use can correctly handle (ignore) a null value. However, I did not find the original code, especially the inelegant one, to get started.

+3
source

Your problem is the createSocket function. Inside this function, you create your own Socket , which implements IDisposable , and you pass this to the outer scope. You should reorganize so that you can use the syntax use socket = new Socket(...) . This can be done by creating a wrapper class that implements IDisposable and correctly places your socket.

0
source

Source: https://habr.com/ru/post/1014537/


All Articles