Elm 模式匹配标记的联合类型

Elm 模式匹配标记的联合类型,elm,algebraic-data-types,Elm,Algebraic Data Types,我有一个标记的联合类型,它包含一些记录数据,如 type Comment = New Content | Edited Content | Flagged Content type alias Content = {id: Int, text: String} 其中,注释类型声明状态 例如,当使用模式匹配按id过滤时,我必须编写 filter Int -> Comment -> Bool filter id comment = case comment of New

我有一个标记的联合类型,它包含一些记录数据,如

type Comment = New Content | Edited Content | Flagged Content

type alias Content = {id: Int, text: String}
其中,
注释
类型声明状态

例如,当使用模式匹配按id过滤时,我必须编写

filter Int -> Comment -> Bool
filter id comment =
  case comment of
    New content -> content.id == id
    Edited content -> content.id == id
    Flagged content -> content.id = id
这是可行的,但我必须为每种情况复制相同的逻辑,而我希望它像

 filter id comment =
   case comment of
     _ content -> content.id == id
使用过滤等功能,这是简单的单行复制,但在基于状态呈现内容时,HTML生成逻辑的复制更为严重

我知道在Elm中,联合类型可以携带不同的“负载”,编译器不喜欢泛型版本,但是在这种情况下,有没有办法告诉编译器所有这些情况都处理相同的记录类型

或者这是一种无效使用联合类型的情况,并且模型的结构应该不同?也许状态是记录类型的一部分

或者这是一种无效使用联合类型的情况,并且模型的结构应该不同

如果所有三个变量始终包含相同的数据,则为“是”

我会在顶部使用一条记录,并为注释的“状态”创建一个标记的联合

type alias Comment =
    { id : Int
    , text : String
    , status : Status
    }


type Status
    = New
    | Edited
    | Flagged
这将便于访问注释的
id
text
。如果您执行
case comment.status of…

的操作,您仍然可以获得详尽的模式匹配的好处,您可以考虑get content部分

例如,如果要添加文本过滤器,则可以进一步抽象

filter : Int -> Comment -> Bool
filter id comment =
  doFilter (\c -> c.id == id) comment

filterText : String -> Comment -> Bool
filterText text comment =
  doFilter (\c -> c.text == text) comment

doFilter : (Content -> Bool) -> Comment -> Bool
doFilter f comment =
  let content = commentContent comment
  in  f content
最后,添加一些功能性样式

doFilter : (Content -> Bool) -> Comment -> Bool
doFilter f = f << commentContent
doFilter:(内容->Bool)->评论->Bool

doFilter f=f感谢您的输入。这是一个很好的方法,但在我的例子中,我决定按照Dogbert在回答中的建议重新构建模型。主要是因为重组后的模型更容易实现排序。
doFilter : (Content -> Bool) -> Comment -> Bool
doFilter f = f << commentContent