我有类型Model
,它描述了泛型类型别名ModelFields
的两种可能状态。我想从ModelFields
类型的实例中提取通用Model
记录。
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
但是榆树不允许它为每个案例表达说
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?
所以我的问题是:如何从ModelFields
获得Model
?还是我做了一些从根本上有缺陷的事情?
UPD。我正在尝试建模的细节。
我有Organism
类型的对象。他们被分为Rank
s。我的服务器对Organism
s进行了一些成对分析,例如。计算两个Similarity
s之间的Distance
和Organism
。我想在不同页面的两个表格中显示这些分析的结果,一页用于Similarity
分析,一页用于Distance
分析。这意味着该表应该可以重复使用以接受任何形式的分析结果。另一方面,这些表有一种常见的模式。他们可以处于两种状态:
endValue
s之间成对比较(Model
在Organism
)的具体结果,因此表格的行和列代表Organism
s。stats
s组(Model
s)之间的统计值(例如,Rank
中的平均值或标准偏差,Organism
),在这种情况下,表格的行和列代表Rank
s。显示哪个Rank
s或Organism
s取决于location
的ModelFields
字段。用户可以单击一个按钮,我想在我的location
函数中更改update
。这种导航变化可能会在ShowEndValues
和ShowStatistics
状态之间切换。这就是我试图从ModelFields
构造函数中解开Model
的原因。我附上一个简单的插图,希望它有助于澄清.
这确实是不可能的。
model
函数中的getModelFields
值将具有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
类型,类似于我们如何尝试统一两个混凝土类型。