如何从使类型别名更具体的联合类型中解包泛型类型别名?
How do I unwrap a generic type alias from a union type which makes the type alias more specific?
我有类型 Model
,它描述了通用类型别名 ModelFields
的两种可能状态。我想从 Model
类型的实例中提取通用 ModelFields
记录。
type Model endValue stats
= ShowEndValues (ModelFields Organism endValue)
| ShowStatistics (ModelFields Rank stats)
type alias ModelFields object results =
{ results : List results
, objects : List object
, cellValue : results -> String
, location : Maybe (Rank, Rank)
}
getModelFields : Model endValue stats -> ModelFields object results
getModelFields model =
case model of
ShowEndValues modelFields ->
modelFields
ShowStatistics modelFields ->
modelFields
但是 Elm 不允许它对每个 case 表达式说
TYPE MISMATCH - Something is off with the 1st branch of this `case` expression:
55| modelFields
#^^^^^^^^^^^#
This `modelFields` value is a:
ModelFields #Organism# #endValue#
But the type annotation on `getModelFields` says it should be:
ModelFields #object# #results#
#Hint#: Your type annotation uses type variable `object` which means ANY type of
value can flow through, but your code is saying it specifically wants a
`Organism` value. Maybe change your type annotation to be more specific? Maybe
change the code to be more general?
所以我的问题是:如何从 Model
得到 ModelFields
?还是我做的事情存在根本性的缺陷?
更新。我正在尝试建模的详细信息。
我有 Organism
类型的对象。它们被分组为 Rank
s。我的服务器对 Organism
、i.g 进行了一些成对分析。计算两个 Organism
之间的 Similarity
和 Distance
。我想在不同页面的两个 table 中显示这些分析的结果,一页用于 Similarity
分析,一页用于 Distance
分析。这意味着 table 应该可以重复使用以接受任何形式的分析结果。
另一方面,这些 table 有一个共同的模式。它们可以处于两种状态:
- 显示
Organism
之间的成对比较(endValue
in Model
)的具体结果,因此 table 的行和列代表 Organism
s.
- 显示
Organism
组 (Rank
s) 之间的统计值(例如平均值或标准差,stats
in Model
),在本例中 table的行和列代表Rank
s.
显示哪些 Rank
或 Organism
取决于 ModelFields
的 location
字段。用户可以单击一个按钮,我想更改 update
函数中的 location
。此导航更改可能会在 ShowEndValues
和 ShowStatistics
状态之间切换。这就是为什么我试图从 Model
构造函数中解开 ModelFields
的原因。我附上了一个简单的插图,希望它有助于澄清。
这确实不行
getModelFields
函数中的 model
值的类型为 Model endValue stats
。这意味着它将是 ShowEndValues
变体,包含 ModelFields Organism endValue
类型的值,或者是 ShowStatistics
包含类型 ModelFields Rank stats
的值的变体。 case
表达式的每个分支解压一个变体并输出 modelFields
值。
现在,让我们尝试确定 case
表达式的类型。我们查看每个分支返回的类型,并尝试找到包含这两种类型的类型(统一它们)。乍一看,它看起来很有希望:两个值都采用 ModelFields a b
形式,因此我们将递归地尝试统一每个子类型。这里我们遇到了一个问题——第一种类型的 a
的类型是 Organism
而第二种类型是 Rank
。没有既是 Organism
又是 Rank
的类型,所以编译失败。
注意:从报错信息可以看出,Elm实际上是在尝试将分支的类型与函数结果类型统一起来。 (我描述了另一个方向,因为我认为它更容易理解。)Elm 遵循的方向也失败了,因为它会递归并尝试统一具体的 Organism
类型和通用的 object
类型,类似地以及我们如何尝试统一两种具体类型。
我有类型 Model
,它描述了通用类型别名 ModelFields
的两种可能状态。我想从 Model
类型的实例中提取通用 ModelFields
记录。
type Model endValue stats
= ShowEndValues (ModelFields Organism endValue)
| ShowStatistics (ModelFields Rank stats)
type alias ModelFields object results =
{ results : List results
, objects : List object
, cellValue : results -> String
, location : Maybe (Rank, Rank)
}
getModelFields : Model endValue stats -> ModelFields object results
getModelFields model =
case model of
ShowEndValues modelFields ->
modelFields
ShowStatistics modelFields ->
modelFields
但是 Elm 不允许它对每个 case 表达式说
TYPE MISMATCH - Something is off with the 1st branch of this `case` expression:
55| modelFields
#^^^^^^^^^^^#
This `modelFields` value is a:
ModelFields #Organism# #endValue#
But the type annotation on `getModelFields` says it should be:
ModelFields #object# #results#
#Hint#: Your type annotation uses type variable `object` which means ANY type of
value can flow through, but your code is saying it specifically wants a
`Organism` value. Maybe change your type annotation to be more specific? Maybe
change the code to be more general?
所以我的问题是:如何从 Model
得到 ModelFields
?还是我做的事情存在根本性的缺陷?
更新。我正在尝试建模的详细信息。
我有 Organism
类型的对象。它们被分组为 Rank
s。我的服务器对 Organism
、i.g 进行了一些成对分析。计算两个 Organism
之间的 Similarity
和 Distance
。我想在不同页面的两个 table 中显示这些分析的结果,一页用于 Similarity
分析,一页用于 Distance
分析。这意味着 table 应该可以重复使用以接受任何形式的分析结果。
另一方面,这些 table 有一个共同的模式。它们可以处于两种状态:
- 显示
Organism
之间的成对比较(endValue
inModel
)的具体结果,因此 table 的行和列代表Organism
s. - 显示
Organism
组 (Rank
s) 之间的统计值(例如平均值或标准差,stats
inModel
),在本例中 table的行和列代表Rank
s.
显示哪些 Rank
或 Organism
取决于 ModelFields
的 location
字段。用户可以单击一个按钮,我想更改 update
函数中的 location
。此导航更改可能会在 ShowEndValues
和 ShowStatistics
状态之间切换。这就是为什么我试图从 Model
构造函数中解开 ModelFields
的原因。我附上了一个简单的插图,希望它有助于澄清。
这确实不行
getModelFields
函数中的 model
值的类型为 Model endValue stats
。这意味着它将是 ShowEndValues
变体,包含 ModelFields Organism endValue
类型的值,或者是 ShowStatistics
包含类型 ModelFields Rank stats
的值的变体。 case
表达式的每个分支解压一个变体并输出 modelFields
值。
现在,让我们尝试确定 case
表达式的类型。我们查看每个分支返回的类型,并尝试找到包含这两种类型的类型(统一它们)。乍一看,它看起来很有希望:两个值都采用 ModelFields a b
形式,因此我们将递归地尝试统一每个子类型。这里我们遇到了一个问题——第一种类型的 a
的类型是 Organism
而第二种类型是 Rank
。没有既是 Organism
又是 Rank
的类型,所以编译失败。
注意:从报错信息可以看出,Elm实际上是在尝试将分支的类型与函数结果类型统一起来。 (我描述了另一个方向,因为我认为它更容易理解。)Elm 遵循的方向也失败了,因为它会递归并尝试统一具体的 Organism
类型和通用的 object
类型,类似地以及我们如何尝试统一两种具体类型。