我有类型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
但是Elm不允许对每个案例表达式都说
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
个。我的服务器对Organism
进行了成对分析,例如计算两个Similarity
之间的Distance
和Organism
。我想在不同页面上的两个表中显示这些分析的结果,一页用于Similarity
分析,而一页用于Distance
分析。这意味着该表应可重复使用以接受任何形式的分析结果。
另一方面,这些表有一个常见的模式。它们可以处于两种状态:
endValue
之间的成对比较(Model
中的Organism
)的具体结果,因此表的行和列表示Organism
。stats
组(Model
s)之间显示统计值(例如Rank
中的平均值或标准偏差,Organism
中的Rank
),在这种情况下,表格的行和列代表Rank
。显示的Organism
或location
取决于ModelFields
的{{1}}字段。用户可以单击一个按钮,我想在我的location
函数中更改update
。此导航更改可能会在ShowEndValues
和ShowStatistics
状态之间切换。这就是为什么我试图从ModelFields
构造函数中解开Model
的原因。我附上一个简单的插图,希望可以帮助阐明。
答案 0 :(得分:1)
这确实是不可能的。
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
类型统一我们如何统一两种具体类型。