pattern-matching - 如何将参数限制为变体类型的仅一种变体

标签 pattern-matching ocaml algebraic-data-types gadt reason

假设我有两种类型,Vector2DVector3D 并且它们被标记(这是正确的术语,对吧?),并且我想编写一个仅运行的函数在 Vector2D 上(或者这里的 vector(two) 更正确吗?),如下所示:

type two;
type three;
type vector('a) = 
  | Vector2D(float, float): vector(two)
  | Vector3D(float, float, float): vector(three);

let first = (a: vector(two)) => {
  switch(a) {
    | (x, y) => x +. y
  }
}

let second = (Vector2D(x, y)) => {
  x +. y
}

let third = ((x, y): vector(two)) => {
  x +.y
}

firstsecond 函数禁止传递 Vector3D,正如我想要的那样,但它们发出警告“此模式匹配并不详尽” ”。

对于first,我想知道为什么这并不详尽,我是否没有将可能的选项限制为Vector2D?对于 second 我猜原因与 first 相同,但是如何用这种语法解决问题呢?

至于third,这个无法编译,因为“此模式匹配 ('a, 'b) 但需要向量(two)”。为什么编译器需要这里有任何元组?函数参数中不能使用解构吗?

编辑:
事实证明,有一个更简单的问题来演示我想要的内容

type state = Solid | Liquid
let splash = (object) => {
  switch(object) {
    | Liquid => "splashing sounds. I guess."
    | Solid => "" // this should not even be possible in the context of this function, and I want to compiler to enforce this
}

最佳答案

关于 GADT 部分,这里的问题是您正在使用bucklescript 及其古老的 4.02.3 编译器版本。 例如,以下代码在 OCaml ≥ 4.03 中运行得非常好:

type two = Two ; 
type three = Three ;
/* Never define abstract types when you want to use them as type level tags,
  your code will only works inside the module defining them, and then
  fail due to injectivity problems.
*/

type vector('a) = 
  | Vector2D(float, float): vector(two)
  | Vector3D(float, float, float): vector(three);

let sum_2 = (Vector2D(x,y)) => x +. y
let sum_3 = (Vector3D(x,y,z)) => x +. y +. z 
let sum_any = (type a, x: vector(a) ) => switch (x) {
  | Vector2D(x,y) => x +. y;
  | Vector3D(x,y,z) => x +. y +. z
}

但它会在 4.02.3 上失败,并出现详尽性警告(应将其视为错误),因为仅在 4.03 中添加了针对带有反驳子句的 GADT 的详尽性检查。

关于pattern-matching - 如何将参数限制为变体类型的仅一种变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58721045/

相关文章:

sql - postgres 中不区分大小写的索引,处理区分大小写的查询?

haskell - 计算向量表达式的范数 ||aW+bX+cY||

algorithm - 特定对象/图像识别任务的最佳方法?

regex - R 中的计数模式匹配

load - ocaml 顶层模块加载

pattern-matching - 查找 int 列表的不同元素

list - 如何在没有 GADT 或数据类型上下文的情况下定义 List 的 Eq 实例

haskell自己的数据类型 - 在数据类型定义中使用符号或数字

coq - 由于多态性功能而出现非阳性现象

jquery - 将字符串与存储变量列表进行匹配