types - 如何从联合类型中解开泛型类型别名,从而使类型别名更具体?
问题描述
我有 type 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 不允许它对每个 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?
所以我的问题是:我如何ModelFields
从Model
?还是我在做一些根本上存在缺陷的事情?
UPD。我正在尝试建模的详细信息。
我有类型的对象Organism
。它们被分组为Rank
s。我的服务器对Organism
s、ig 计算Similarity
和Distance
两个Organism
s 之间进行了一些成对分析。我想在不同页面的两个表中显示这些分析的结果,一页用于Similarity
分析,一页用于Distance
分析。这意味着该表应该可重复使用以接受任何形式的分析结果。另一方面,这些表有一个共同的模式。它们可以处于两种状态:
- 显示 s 之间成对比较 (
endValue
inModel
)的具体结果Organism
,因此表格的行和列表示Organism
s。 - 显示 s 的组 ( s)之间的统计值(例如平均值或标准差,
stats
单位为) ,在这种情况下,表格的行和列表示s。Model
Rank
Organism
Rank
显示哪个Rank
s 或Organism
s 取决于 的location
字段ModelFields
。用户可以单击一个按钮,我想更改location
我的update
功能。这种导航变化可能会在ShowEndValues
和ShowStatistics
状态之间切换。这就是为什么我试图ModelFields
从Model
构造函数中解开。我附上了一个简单的插图,希望它有助于澄清。
解决方案
这确实是不可能的。
函数中的model
值getModelFields
将具有 type Model endValue stats
。这意味着它要么是ShowEndValues
包含 type 值的变体,要么是包含 typed 值ModelFields Organism endValue
的变体。表达式的每个分支解包一个变体并输出值。ShowStatistics
ModelFields Rank stats
case
modelFields
现在,让我们尝试确定case
表达式的类型。我们查看每个分支返回的类型,并尝试找到包含这两种类型的类型(统一它们)。乍一看,它看起来很有希望:两个值都在格式中,ModelFields a b
因此我们将递归地尝试统一每个子类型。在这里我们遇到了一个问题——a
第一种类型有 typeOrganism
而第二种是Rank
. 没有两者兼有的类型,Organism
因此Rank
编译失败。
注意:从错误信息中可以看出,Elm 实际上试图将分支的类型与函数结果类型统一起来。(我描述了另一个方向,因为我认为它更容易理解。) Elm 遵循的方向也失败了,因为它会递归并尝试将具体Organism
类型与泛型object
类型统一,类似于我们尝试统一两种具体类型的方式。
推荐阅读
- java - 如何使用 java 8 或任何最近使用 java 访问的方法从共享位置访问文件?
- python - 如何处理上传到 PyPI 的“平台特定动态库”问题?
- networking - Kubernetes Pod 出站流量 DNAT 规则
- c# - 如何通过单击c#中的另一个取消按钮来取消任务运行?
- java - Apache FOP 和 Java 图像问题 - 结合多个来源
- c++ - 如何检查为什么链接需要一些符号?
- c++builder - Delphi for...in 在 C++Builder 中
- iis - 分析故障转储文件时,DLL 未在 WinDbg 中下载
- android - 客户端流式传输 gRPC 请求时出现 OutOfMemoryError
- oracle - Oracle 查询中 XML 处理期间的错误