Url Parsing in F#

open System
open System.Net

// We'll parse this example URL, which includes a
// scheme, authentication info, host, port, path,
// query params, and query fragment.
let s = "postgres://user:pass@host.com:5432/path?k=v#f"

// Parse the URL and ensure there are no errors.
let u = Uri(s)

// Accessing the scheme is straightforward.
printfn "%s" u.Scheme

// UserInfo contains all authentication info; we can extract
// username and password from it.
let userInfo = u.UserInfo.Split(':')
printfn "%s" u.UserInfo
printfn "%s" userInfo.[0]
printfn "%s" userInfo.[1]

// The Host contains both the hostname and the port,
// if present. Use Uri.Host and Uri.Port to extract them.
printfn "%s" u.Authority
printfn "%s" u.Host
printfn "%d" u.Port

// Here we extract the path and the fragment after
// the #.
printfn "%s" u.AbsolutePath
printfn "%s" u.Fragment

// To get query params in a string of k=v format,
// use Query. You can also parse query params
// into a map using HttpUtility.ParseQueryString.
printfn "%s" u.Query
let query = HttpUtility.ParseQueryString(u.Query)
printfn "%A" query
printfn "%s" (query.["k"])

Running our URL parsing program shows all the different pieces that we extracted:

postgres
user:pass
user
pass
host.com:5432
host.com
5432
/path
#f
?k=v
System.Collections.Specialized.NameValueCollection
v

In this F# version:

  1. We use the System.Uri class to parse the URL, which provides similar functionality to Go’s url.Parse.

  2. The UserInfo property gives us the username and password together, which we split manually.

  3. Instead of SplitHostPort, we use the Host and Port properties of the Uri class.

  4. The Query property gives us the raw query string, and we use HttpUtility.ParseQueryString to parse it into a NameValueCollection.

  5. F# uses printfn for formatted printing, similar to Go’s fmt.Println.

  6. Error handling is not explicitly shown here, but you could wrap the Uri creation in a try-catch block if needed.

This example demonstrates how to parse and extract information from URLs in F#, covering similar concepts to the original Go example.