Say I have a union type like this:
type Route
= Home
| License
| UserProfile { username : String }
| Search { query : String }
| SomeOtherPage
In practice I frequently need to work with subsets of this union. For example:
type StaticRoute = Home | License
I would like to be able to define functions which accept subsets like the above, instead of the wider Route
.
I don't want to nest StaticRoute
inside of Route
, like so:
type Route
= Static StaticRoute
| UserProfile { username : String }
| Search { query : String }
| SomeOtherPage
This is because I want to be able to define many different subsets of Route
, some of which could overlap:
type StaticRoute = Home | License
type RouteWithServerRendering = Home | Search { query : String }
type LoggedInRoute = SomeOtherPage
-- and so on…
How then can I define subsets of Route
without repeating definitions?
Jasper Woudenberg recently posted Conversion functions, five stars , which advocates for having similar types and using conversion functions to translate between one type to another.
In your case, it might look like this:
module Route exposing (fromStaticRoute, toStaticRoute)
fromStaticRoute : StaticRoute -> Route
fromStaticRoute staticRoute =
case staticRoute of
Static.Home ->
Home
Static.License ->
License
toStaticRoute : Route -> Maybe StaticRoute
toStaticRoute route =
case route of
Home ->
Just Static.Home
License ->
Just Static.License
_ ->
Nothing