re: Use opaque types in Elm! VIEW POST

TOP OF THREAD FULL DISCUSSION
re: Great explanation of opaque types, thank you! What do you think of the following additional improvement? The model currently specifies both title...
 

Good question!

The issue is that a type alias is just a new name for a type (an alias). Therefore, TitleString is a just new way to say String. This means that Question.titleFromString model.body would still compile, even when using TitleString in your Model and Question API. The compiler would see String everywhere.

We can use an opaque type! Imagine we define a Question.TitleField module with this API:

module Question.TitleField exposing (TitleField, blank, title, view)

import Html exposing (Html)
import Html.Attributes as Attributes
import Html.Events as Events
import Question

type TitleField
    = TitleField String

blank : TitleField
blank =
    TitleField ""

title : TitleField -> Result String Question.Title
title (TitleField value) =
    Question.titleFromString value

view : TitleField -> Html TitleField
view (TitleField value) =
    Html.input
        [ Events.onInput TitleField
        , Attributes.value value
        , Attributes.type_ "text"
        ]
        []

This module ties a a TitleField value with its form field view and its validation. Finally, we use TitleField in our Model, using blank to initialize it, title for validation, and view to render it!

composable-form can help you write this:

module Question.TitleField exposing (TitleField, blank, form)

import Form

type TitleField
    = TitleField String

blank : TitleField
blank =
    TitleField ""

form : Form TitleField Question.Title
form =
    Form.textField
        { parser = Question.titleFromString
        , value = \(TitleField value) -> value
        , update = \newValue oldValue -> TitleField newValue
        , attributes =
            { label = "Question title"
            , placeholder = "Type the statement of your question..."
            }
        }
 

I'm glad this led back to opaque types. 8-D Using something like TitleField type is probably too much for the simple example, but a great solution for a site that has to be really robust! hecrj/composable-form looks great, I'm going to check that out too.

As for type aliases... I don't know enough about compiler design to have an informed opinion, but what I described is how I would "want" type aliases to work. I totally understand that after being compiled they're all just Strings (in this example), but if the coder specifies a different name I think I want a step somewhere that will catch that if the wrong name is used. But your TitleField solution is better anyway, it provides a lot more than just a new name for a type. 8-)

code of conduct - report abuse