Create upwards compatible APIs
This topic has been covered by Elm Patterns​
Problem
Solution
Movie.elm
1
type Movie =
2
Movie
3
{ title : String
4
, rating : Int
5
, -- adding a field will destroy the function below
6
}
7
​
8
new : String -> Int -> Movie
9
new title rating =
10
Movie
11
{ title = title
12
, rating = clamp 1 5 rating
13
}
Copied!
Movie.elm
1
type Movie =
2
Movie
3
{ title : String
4
, rating : Int
5
, director : Maybe String
6
}
7
​
8
fromTitle : String -> Movie -> Movie
9
fromTitle title =
10
Movie
11
{ title : title
12
, rating : 0
13
, director : Nothing
14
}
15
​
16
withRating : Int -> Movie -> Movie
17
withRating rating (Movie movie) =
18
{ movie | rating = clamp 1 5 rating }
19
​
20
withDirector : String -> Movie -> Movie
21
withDirector director (Movie movie) =
22
{ movie | director = director }
Copied!

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:
1
Movie.fromTitle "Life of Brian"
2
|> Movie.withDirector "Terry Jones"
3
|> Movie.withRating 5
Copied!

Further Reading