I have a type like,
type Post
= Blog String String
| Announcement String String
And a function like,
upcaseTitle : Post -> Post
upcaseTitle post =
case post of
Blog title body ->
{ post | title = String.toUpper title }
Announcement title body ->
{ post | title = String.toUpper title }
I would like to write code like,
upcaseTitle : Post -> Post
upcaseTitle post =
case post of
Post title body ->
{ post | title = String.toUpper title }
I want to add one clause in my case
statement that matches all Post
types and extracts the common String
, title
, since it is shared across all variations of my union type.
Is this possible in elm?
Nope, not possible. In a few other languages this can be achieved using or-patterns (even then you still have to enumerate and deconstruct every variant, but they can share a single body), but Elm aims to be a simpler language than those.
One option is to extract the common branch body into a function:
upcaseTitle : Post -> Post
upcaseTitle post =
let
setTitle title =
{ post | title = String.toUpper title }
in
case post of
Blog title body ->
setTitle title
Announcement title body ->
setTitle title
Another is to define a separate function to extract just the title:
getTitle : Post -> String
getTitle post =
case post of
Blog title body ->
title
Announcement title body ->
title
upcaseTitle : Post -> Post
upcaseTitle post =
{ post | title = String.toUpper (getTitle post) }
But if every variant of your custom type is identical, I'd start by questioning the design of that type. Maybe it would be better to use a record where the post type is just a field instead?
type PostType
= Blog
| Announcement
type Post =
{ title : String
, body : String
, postType : PostType
}