如何从自定义类型的多个变体中提取值?
How do you extract the value from multiple variants of a custom type?
我有这样的类型,
type Post
= Blog String String
| Announcement String String
还有一个函数,
upcaseTitle : Post -> Post
upcaseTitle post =
case post of
Blog title body ->
{ post | title = String.toUpper title }
Announcement title body ->
{ post | title = String.toUpper title }
我想写这样的代码,
upcaseTitle : Post -> Post
upcaseTitle post =
case post of
Post title body ->
{ post | title = String.toUpper title }
我想在我的 case
语句中添加一个匹配所有 Post
类型的子句,并提取常见的 String
、title
,因为它是所有共享的我的联合类型的变体。
这在榆树中可能吗?
不,不可能。在一些其他语言中,这可以使用 or-patterns 来实现(即使那样你仍然必须枚举和解构每个变体,但它们可以共享一个 body),但 Elm 的目标是成为一种比那些。
一个选项是将公共分支 body 提取到一个函数中:
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
另一种是定义一个单独的函数来仅提取标题:
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) }
但如果您的自定义类型的每个变体都相同,我会首先质疑该类型的设计。也许最好使用 post 类型只是一个字段的记录?
type PostType
= Blog
| Announcement
type Post =
{ title : String
, body : String
, postType : PostType
}
我有这样的类型,
type Post
= Blog String String
| Announcement String String
还有一个函数,
upcaseTitle : Post -> Post
upcaseTitle post =
case post of
Blog title body ->
{ post | title = String.toUpper title }
Announcement title body ->
{ post | title = String.toUpper title }
我想写这样的代码,
upcaseTitle : Post -> Post
upcaseTitle post =
case post of
Post title body ->
{ post | title = String.toUpper title }
我想在我的 case
语句中添加一个匹配所有 Post
类型的子句,并提取常见的 String
、title
,因为它是所有共享的我的联合类型的变体。
这在榆树中可能吗?
不,不可能。在一些其他语言中,这可以使用 or-patterns 来实现(即使那样你仍然必须枚举和解构每个变体,但它们可以共享一个 body),但 Elm 的目标是成为一种比那些。
一个选项是将公共分支 body 提取到一个函数中:
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
另一种是定义一个单独的函数来仅提取标题:
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) }
但如果您的自定义类型的每个变体都相同,我会首先质疑该类型的设计。也许最好使用 post 类型只是一个字段的记录?
type PostType
= Blog
| Announcement
type Post =
{ title : String
, body : String
, postType : PostType
}