🌳
Walking though the Elm woods
  • Introduction
  • Structure of the book
  • Frequently asked questions
    • How can different types share data?
    • How to break Dependency Cycles?
    • How to structure an Elm project?
    • How to turn a Msg into a Cmd Msg?
    • How to update nested Records?
    • What are comparable types?
    • Why are Booleans bad?
    • 🔜Future topics
  • Recipes
    • Writing a Single Page Application
      • Share state across pages
      • Debounced Validation
      • Reusable views
    • Making impossible states Impossible
      • Non empty lists using Zippers
      • Restrict records using Opaque Types
      • Write safer functions using Phantom Types
    • Designing Elm package APIs
      • Create upwards compatible APIs
    • 🔜Future topics
  • Frameworks and packages
    • elm/parser
    • mdgriffith/elm-ui
    • 🔜Future topics
Powered by GitBook
On this page
  • Question
  • Answer
  • Further Reading

Was this helpful?

  1. Recipes
  2. Designing Elm package APIs

Create upwards compatible APIs

PreviousDesigning Elm package APIsNextFuture topics

Last updated 4 years ago

Was this helpful?

This topic has been covered by

Movie.elm
type Movie =
    Movie 
        { title : String
        , rating : Int
        , -- adding a field will destroy the function below
        }

new : String -> Int -> Movie
new title rating =
  Movie
    { title = title
    , rating = clamp 1 5 rating
    }
Movie.elm
type Movie =
    Movie 
        { title : String
        , rating : Int
        , director : Maybe String
        }

fromTitle : String -> Movie -> Movie
fromTitle title =
    Movie 
        { title : title
        , rating : 0
        , director : Nothing
        }

withRating : Int -> Movie -> Movie
withRating rating (Movie movie) =
    { movie | rating = clamp 1 5 rating }

withDirector : String -> Movie -> Movie
withDirector director (Movie movie) =
    { movie | director = director }

Question

How can I define my type, such that I can add features without breaking the API?

Answer

First write a constructor fromTitle that only uses as few arguments as possible. Next add partial constructors for every feature of your type: withRating and withDirector.

Now creating a new Movie can be done like this:

Movie.fromTitle "Life of Brian"
|> Movie.withDirector "Terry Jones"
|> Movie.withRating 5

Further Reading

📄Article: by Charlie Koster

🎥Video: by Brian Hicks

❗Example:

❗Example:

❗Example: from BrianHicks/elm-particle

❗Example: from dillonkearns/elm-graph

❗Example: from Orasund/pixelengine

Elm Patterns
With* Functions in Elm
Robot Buttons from Mars
NoRedInk/elm-json-decode-pipeline
Chadtech/random-pipeline
Particle Type
Request Type
Image Type