我正在尝试将类型建模为联合,其中该联合的每个成员都具有与所有其他成员相同的属性。
我目前正在这样实现:
type alias File = {
name : String
}
type CommonFileState extra = CommonFileState {
id : String
, file : File
} extra
type alias ValidFileState = CommonFileState {
validatedAt : Int
}
type alias InvalidFileState = CommonFileState {
reason : String
}
type alias LoadingFileState = CommonFileState {}
type FileState = Valid ValidFileState | Invalid InvalidFileState | Loading LoadingFileState
现在,如果我想读取任何给定FileState
上的那些公共属性之一,则必须与联合的每个成员匹配:
getId : FileState -> String
getId fileState = case fileState of
Valid (CommonFileState {id} extra) -> id
Invalid (CommonFileState {id} extra) -> id
Loading (CommonFileState {id} extra) -> id
这对我来说是错的,因为我必须为每个成员复制属性访问权限。如果我需要以某种方式操纵此属性(例如,将某些内容连接到字符串上),则还必须重复此操作。
我希望能够轻松访问我的联合的公共属性,并对这些公共属性进行操作。
当我开始寻找实现此目的的其他方法时,我发现一种替代方法是将联合嵌套在记录中,该记录也具有公共属性:
type alias ValidCurrentFileState = {
validatedAt : Int
}
type alias InvalidCurrentFileState = {
reason : String
}
type alias LoadingCurrentFileState = {}
type CurrentFileState = Valid ValidCurrentFileState | Invalid InvalidCurrentFileState| Loading LoadingCurrentFileState
type alias File = {
name : String
}
type alias FileState = {
id : String
, file : File
, currentState : CurrentFileState
}
getId : FileState -> String
getId {id} = id
但是这很尴尬,因为我必须命名嵌套的并集,这增加了不必要的间接访问级别:“文件状态”和“ 当前文件状态”在概念上是相同的。
还有没有其他方法可以解决我提到的问题吗?
答案 0 :(得分:1)
我认为您正在思考这种错误的方法。
(在Elm中)建模的目的是捕获数据的可能状态,并在模型中排除“不可能”状态,以便编译器可以静态地防止代码每次创建此类状态。
一旦对模型感到满意,就可以编写所需的帮助程序,以使核心逻辑易于表达和维护。
我怀疑我通常会采用第二种方法,但是我不知道您需要解决的所有问题。