Url Parsing in Elm

Our URL parsing program demonstrates how to parse and extract information from URLs in Elm. Here’s the full source code:

module Main exposing (main)

import Html exposing (Html, div, text)
import Url

main : Html msg
main =
    let
        urlString =
            "postgres://user:pass@host.com:5432/path?k=v#f"

        maybeUrl =
            Url.fromString urlString
    in
    case maybeUrl of
        Just url ->
            div []
                [ text ("Scheme: " ++ url.protocol)
                , text ("User: " ++ Maybe.withDefault "" url.username)
                , text ("Password: " ++ Maybe.withDefault "" url.password)
                , text ("Host: " ++ url.host)
                , text ("Port: " ++ Maybe.withDefault "" (Maybe.map String.fromInt url.port_))
                , text ("Path: " ++ url.path)
                , text ("Query: " ++ Maybe.withDefault "" url.query)
                , text ("Fragment: " ++ Maybe.withDefault "" url.fragment)
                ]

        Nothing ->
            div [] [ text "Invalid URL" ]

Let’s break down the important parts of this code:

We start by importing the necessary modules, including Url for URL parsing.

import Url

We define our main function, which is the entry point of our Elm application. Inside this function, we define our example URL string:

urlString =
    "postgres://user:pass@host.com:5432/path?k=v#f"

We then use Url.fromString to parse the URL string into a Maybe Url type:

maybeUrl =
    Url.fromString urlString

We use a case expression to handle the Maybe Url. If the URL is valid, we extract and display various components of the URL:

  • url.protocol: The scheme (protocol) of the URL
  • url.username: The username (if present)
  • url.password: The password (if present)
  • url.host: The host part of the URL
  • url.port_: The port number (if specified)
  • url.path: The path component of the URL
  • url.query: The query string (if present)
  • url.fragment: The fragment identifier (if present)

Note that some of these fields are of type Maybe, so we use Maybe.withDefault to provide a default value when the field is not present.

If the URL is invalid, we simply display an “Invalid URL” message.

To run this Elm program, you would typically compile it to JavaScript and run it in a web browser. The output would be displayed as HTML elements on the page, showing the parsed components of the URL.

This example demonstrates how Elm’s type system and Maybe type help in safely handling URL parsing, ensuring that we always have a valid URL structure or an explicit indication of an invalid URL.