Write safer functions using Phantom Types

type alias LoginForm =
    { username : String
    , password : String
    , isValid : Bool
    }

{-| Creates a User

Only use this function if the LoginForm was validated.
-}
createUser : LoginForm -> User
createUser loginForm =
    if loginForm.isValid then
        User.create loginForm.username
    else
        Debug.todo "This should not happen."

Question

How can I ensure that a user can only be created with a valid login form?

Answer

Use a so called Phantom Type:

type LoginForm valid = --valid is not used in the definition
    LoginForm
        { username : String
        , password : String
        }
        
type Valid = Valid

Use LoginForm () for unvalidated forms and LoginForm Valid for validated ones.

Further reading

Last updated